473,946 Members | 1,693 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Template oddness with libpqxx

Salve. I'm running into a compilation problem trying to write some
code using libpqxx[0] ( <http://pqxx.tk/> )'s pqxx::Connectio n and
pqxx::Transacto r classes. I seem to be running into a problem with
templates that I do not understand.

I have a class that provides a Transactor (a functor that operates on a
database, in pqxx) to check for sessions. The interface is as follows:

--SessionTransact ion.hpp--
#ifndef SESSIONTRANSACT ION
#define SESSIONTRANSACT ION

#include <string>
#include <pqxx/transactor.h>

#include "Session.hp p"

namespace lawn {
// slight naming goof here, NMF --owen
// XXX Fix this class name?
class SessionTransact ion: public pqxx::Transacto r {
public:
SessionTransact ion (unsigned long sessionid,
const std::string& host);

void operator() (argument_type &T);

/// Sends data to mtarget, if defined.
void OnCommit ();

/// PQXX passes the transactor in as const, so we need a way to
/// communicate data back to the originating Session.
void SetSession (Session* target);

private:
bool mlogin;
unsigned long msid;
std::string mhost;
Session* mtarget;
};
}

#endif
--EOF--

The implementation for this class has not yet been written. I am
including this header in another part of the project, which *has* been
(partially) written, and attempting to compile only that file while I
complete the implementation and work out how SessionTransact ion needs
to behave.

--Session.hpp--
#ifndef SESSION
#define SESSION

#include <cgicc/Cgicc.h>

#include "Database.h pp"

namespace lawn {
class Session {
public:
Session (const cgicc::Cgicc& cgi, DB_Handle db);

void SetUserid (unsigned long userid); //< called by
SessionTransact ion::OnCommit, mainly
private:
bool mloggedin;
unsigned long muserid;
};
};

#endif
--EOF--

--Session.cpp--
#include <sstream>
#include <vector>

#include "Session.hp p"
#include "SessionTransac tion.hpp"

namespace lawn {
Session::Sessio n (const cgicc::Cgicc& cgi, DB_Handle db):
mloggedin (false),
muserid (0)
{
cgicc::CgiEnvir onment env = cgi.getEnvironm ent ();
bool foundid = false;
unsigned long sessionid = 0;
std::vector<cgi cc::HTTPCookie> cookies = env.getCookieLi st ();

for (std::vector<cg icc::HTTPCookie >::iterator i = cookies.begin ();
i != cookies.end ();
i++) {
if (i->getName () == "lawn_sessi on") {
foundid = true; // it's possible to find an id of 0
std::stringstre am idstream (i->getValue ());
idstream >> sessionid;
}
}

if (foundid) {
SessionTransact ion strans (sessionid, env.getRemoteAd dr ());
strans.SetSessi on (this);

db->Perform (strans, 1); // This is line 28 in Session.cpp
}
};
}
--EOF--

All of which conforms to the way the examples in the libpqxx
distribution seem to be written. However, upon attempting to compile
Session.cpp into Session.o, the following errors occur:

[oj@acolyte src]$ make Session.o
g++ -g -O3 -Wall -pedantic -ansi -I/usr/local/pqxx/include -c -o
Session.o Session.cpp
/usr/local/pqxx/include/pqxx/connection.h: In member function `void
pqxx::Connectio n::Perform(cons t TRANSACTOR&, int) [with TRANSACTOR =
lawn::SessionTr ansaction]':
Session.cpp:28: instantiated from here
/usr/local/pqxx/include/pqxx/connection.h:29 6: `X' has incomplete type
/usr/local/pqxx/include/pqxx/connection.h:29 6: storage size of `X'
isn't known
/usr/local/pqxx/include/pqxx/connection.h:29 7: no match for call to `(
lawn::SessionTr ansaction) (<typeprefixerr or>&)'
SessionTransact ion.hpp:14: candidates are: void
lawn::SessionTr ansaction::oper ator()(pqxx::Tr ansaction&)
/usr/local/pqxx/include/pqxx/connection.h:30 1: invalid use of undefined
type `
const struct pqxx::in_doubt_ error'
/usr/local/pqxx/include/pqxx/connection.h:40 : forward declaration of
`const
struct pqxx::in_doubt_ error'
/usr/local/pqxx/include/pqxx/connection.h:30 1: warning: `...' handler
must be
the last handler for its try block
make: *** [Session.o] Error 1

It looks to me like the compiler (G++ 3.2.2) believes that
SessionTransact ion is an incomplete specialisation of something. For
hints, I had a look at the referenced section of connection.h:

--connection.h segment--
template<typena me TRANSACTOR>
inline void Connection::Per form(const TRANSACTOR &T,
int Attempts)
//[t4]
{
if (Attempts <= 0) return;

bool Done = false;

// Make attempts to perform T
// TODO: Differentiate between db-related exceptions and other
exceptions?
do
{
--Attempts;

// Work on a copy of T2 so we can restore the starting situation if
need be
TRANSACTOR T2(T);
try
{
typename TRANSACTOR::arg ument_type X(*this, T2.Name());
T2(X); // Line 296
X.Commit(); // Line 297
Done = true;
}
catch (const in_doubt_error &)
{
// Not sure whether transaction went through or not. The last
thing in
// the world that we should do now is retry.
T2.OnDoubt();
throw;
}
catch (const PGSTD::exceptio n &e)
{
// Could be any kind of error.
T2.OnAbort(e.wh at());
if (Attempts <= 0) throw;
continue;
}
catch (...)
{
// Don't try to forge ahead if we don't even know what happened
T2.OnAbort("Unk nown exception");
throw;
}

T2.OnCommit();
} while (!Done);
}
--End of segment--

Interestingly, other files that use connection.h but do not call
pqxx::Connectio n::Perform (...) compile fine, as do the various
examples provided with the library.

Any thoughts, or should I take this to the libpqxx guys and leave this
july group alone?

--Owen

[0] I know where the libpqxx support group is as well and will be
posting there shortly; I suspect the problem is with my understanding
of templates, hence my post here.
Jul 19 '05 #1
3 3609
> void operator() (argument_type &T);

what is pqxx::Transacto r::argument_typ e?

if (foundid) {
SessionTransact ion strans (sessionid, env.getRemoteAd dr ());
strans.SetSessi on (this);

db->Perform (strans, 1); // This is line 28 in Session.cpp
if you comment out line 28, does the compiler still complain?

[oj@acolyte src]$ make Session.o
g++ -g -O3 -Wall -pedantic -ansi -I/usr/local/pqxx/include -c -o
Session.o Session.cpp
/usr/local/pqxx/include/pqxx/connection.h: In member function `void
pqxx::Connectio n::Perform(cons t TRANSACTOR&, int) [with TRANSACTOR =
lawn::SessionTr ansaction]':
Session.cpp:28: instantiated from here
/usr/local/pqxx/include/pqxx/connection.h:29 6: `X' has incomplete type
/usr/local/pqxx/include/pqxx/connection.h:29 6: storage size of `X'
isn't known
/usr/local/pqxx/include/pqxx/connection.h:29 7: no match for call to `(
lawn::SessionTr ansaction) (<typeprefixerr or>&)'
SessionTransact ion.hpp:14: candidates are: void
lawn::SessionTr ansaction::oper ator()(pqxx::Tr ansaction&)
it looks like the compiler believes pqxx::Transacto r::argument_typ e is
pqxx::Transacti on?
/usr/local/pqxx/include/pqxx/connection.h:30 1: invalid use of undefined
type `
const struct pqxx::in_doubt_ error'
invalid use of _undefined type_ pqxx::in_doubt_ error
/usr/local/pqxx/include/pqxx/connection.h:40 : forward declaration of
`const
struct pqxx::in_doubt_ error'
/usr/local/pqxx/include/pqxx/connection.h:30 1: warning: `...' handler
must be
the last handler for its try block
make: *** [Session.o] Error 1

It looks like 'X' is what we need to look at.

--connection.h segment--
template<typena me TRANSACTOR>
inline void Connection::Per form(const TRANSACTOR &T,
int Attempts) // Work on a copy of T2 so we can restore the starting situation if
need be
TRANSACTOR T2(T);
try
{
typename TRANSACTOR::arg ument_type X(*this, T2.Name());
T2(X); // Line 296
X.Commit(); // Line 297
Done = true;


Is argument_type a non-leaf class with some undefined pure virtuals?

Not fun. Good luck.
Shane
Jul 19 '05 #2
Shane Neph wrote:
void operator() (argument_type &T);
what is pqxx::Transacto r::argument_typ e?


According to the documentation, argument_type is used to define the QoS
that your transactor provides (non-transaction, normal transaction,
robust transaction at the cost of some speed) using children of
pqxx::Transacti onItf. pqx::Transactor ::argument_type is
pqxx::Transacti on.

According to the source:

class Transactor
{
public:
...
/// Define transaction class to use as a wrapper for this code.
/** Select the quality of service for your transactor by overriding
this in
* your derived class.
*/
typedef Transaction argument_type;
....

if (foundid) {
SessionTransact ion strans (sessionid, env.getRemoteAd dr ());
strans.SetSessi on (this);

db->Perform (strans, 1); // This is line 28 in Session.cpp


if you comment out line 28, does the compiler still complain?


Commenting out that line does indeed allow the file to compile, which
is what led me to wonder about libpqxx's code in the first place rather
than assuming the library was beyond reproach.
/usr/local/pqxx/include/pqxx/connection.h:30 1: invalid use of
undefined type `
const struct pqxx::in_doubt_ error'


invalid use of _undefined type_ pqxx::in_doubt_ error


That's inside the library. There shouldn't be anything going on that'd
cause in_doubt_error to be undefined iff I call connection::Per form
(...), though.
/usr/local/pqxx/include/pqxx/connection.h:40 : forward declaration of
`const
struct pqxx::in_doubt_ error'
/usr/local/pqxx/include/pqxx/connection.h:30 1: warning: `...'
handler must be
the last handler for its try block
make: *** [Session.o] Error 1


It looks like 'X' is what we need to look at.


X is, in this case, an instance of lawn::SessionTr ansaction, which *is*
my code.
--connection.h segment--
template<typena me TRANSACTOR>
inline void Connection::Per form(const TRANSACTOR &T,
int Attempts)

// Work on a copy of T2 so we can restore the starting
situation if need be
TRANSACTOR T2(T);
try
{
typename TRANSACTOR::arg ument_type X(*this, T2.Name());
T2(X); // Line 296
X.Commit(); // Line 297
Done = true;


Is argument_type a non-leaf class with some undefined pure virtuals?


*checks*

You know, the documentation leads to me wonder if this might not be the
case. The source, however, says that all pure-virtual functions in the
parent pqxx::Transacti onItf class are actually defined in
pqxx::Transacti on.
Not fun. Good luck.


Not at all. It looks like a simple concept on paper, too. Thanks,
Owen
Jul 19 '05 #3
Something to watch for, also, is circular dependencies. They often give
hard-to-diagnose error messages similar in nature to this one, I believe (I
haven't used g++ in a long time). Draw out a directed graph of your
dependencies in this case to see if you get a circle. Forward declarations
can sometimes be helpful, though I'm not exactly a "pro" at this yet.

Jul 19 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3358
by: Oplec | last post by:
Hi, I'm learning C++ as a hobby using The C++ Programming Language : Special Edition by Bjarne Stroustrup. I'm working on chpater 13 exercises that deal with templates. Exercise 13.9 asks for me to turn a previously made String class that deals with char's into a templated String class that uses the template parameter C instead of char. I thought it would be fairly simple to do this exercise, but I encoutered many errors for my...
31
3581
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will return. I tried to write something like this: template <class Type1, class Type2, class Type3> Type3 findMin(Type1 x, Type2 y){ return (x < y) ? x : y;
1
1718
by: Toby White | last post by:
Can ayone tell me what the expected behaviour of the following snippet is: <?xml version="1.0" encoding="UTF-8" ?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:cml="http://www.xml-cml.org/schema/CML2/Core"> <head /> <body> <cml:cml id='mol_1'/> <p>
3
1801
by: John Abel | last post by:
Hi, I'm running Python 2.3.5/2.4.2 on OSX 10.4.2, and am trying to run CGI scripts using the builtin Apache. For ease, I've symlinked my custom modules into the /Library/Python/2.3/site-packages directory, and they import OK via command line python. However, when I perform the import from a cgi script, python fails to find the module. It is definately something to do with the symlink, as the CGI works OK if I copy the directory into...
2
2034
by: Rudy Ray Moore | last post by:
Whenever I get any error with Vc++7.1/.net/2003, it is followed by huge ammounts of "template assistance" error messaging referencing template code (MTL) that has nothing to do with the error. This makes it difficult to spot errors. For example, F4 to "jump to next error" just jumps ot the next "template assistance" message. And since there are hundreds of them, this is quite obnoxious. Can I disable these things? Why is MSVC...
19
7978
by: aaragon | last post by:
Hi everyone. A very simple question. I would like to know what is better in terms of performance. I want to use a simple function to obtain the minimum of two values. One way could be using a macro: #define min(a,b) ((a<b)?a:b) I thought that another way could be to use a template function: template <class T> T min<T a, T b>
3
3769
by: Hamilton Woods | last post by:
Diehards, I developed a template matrix class back around 1992 using Borland C++ 4.5 (ancestor of C++ Builder) and haven't touched it until a few days ago. I pulled it from the freezer and thawed it out. I built a console app using Microsoft Visual C++ 6 (VC++) and it worked great. Only one line in the header file had to be commented out. I built a console app using Borland C++ Builder 5. The linker complained of references to...
45
3003
by: charles.lobo | last post by:
Hi, I have recently begun using templates in C++ and have found it to be quite useful. However, hearing stories of code bloat and assorted problems I decided to write a couple of small programs to check. What I expected was that there would be minor code bloat and some speed improvement when using templates. However... I wrote a basic list container (using templates), and a list container (using virtual derived classes). I also tried...
1
1519
by: cedarmillxing215 | last post by:
The oddness is on the last line of code. This is stripped down as far as I could figure, and I provide several similar examples that work as expected. I have no idea whether this is a compiler bug or my not understanding how the << overload is chosen. -Chris -------------------- #include <iostream>
0
9979
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11556
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10685
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9883
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8245
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7412
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6111
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6327
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3538
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.