问题描述
首先,请原谅我的英语不好.我正在创建一个类,并且需要实例化一个类,该类包含在依赖于特征的数据类型中……最好用源代码进行解释.
想象以下情况...我有一个包含其实现的类(特征)...
Well, first excuse my bad English. I am making a class and I need to instantiate a class that contains within a data type that depends on a trait ...... best explained with the source code.
Imagine the following scenario... i have a class (trait) wich contains their implementations...
template <typename T>
struct ClassATraits{
};
template <>
struct ClassATraits<Class>
{
typedef Class Some;
typedef Class::Some2 Result;
static std::string funct(const Arg& conn)
{
return Some.funct();
}
}
struct ClassATraits<Class2>
{
typedef Class2 Some;
typedef Class2::Some2 Result;
static std::string funct(const Arg& conn)
{
return Some.funct();
}
}
template <typename T, typename ATraits = ClassATraits<T> >
class ClassA {
typedef ATraits Trait;
typedef typename ATraits::Some Some;
public:
typedef typename ATraits::Some2 Result;
DBConnection():
conn()
{
}
}
现在我上课了.....
now i have the class.....
template <typename typeBD>
class Executor {
typedef ClassA<typeBD>::Result Result; //<--- there is
public:
Executor();
virtual ~Executor();
bool isActive();
Result result();
virtual void exec(std::string query) = 0;
protected:
bool active;
Result queryResult;
};
但是gnu编译器g ++出现了错误:
but there the gnu compiler g++ throw the error:
type ‘ClassA<typeBD, ClassATraits<T> >’ is not derived from type ‘Executor<typeBD>’
推荐答案
typedef typename ATraits::Some2 Result;
应该可能是:
Should probably be:
typedef typename ATraits::Result Result;
因为您没有以下成员:
Because you don''t have a data member of:
ClassATraits<class>::Some2
您对ClassATraits<>的双重声明;看起来也有些时髦.
Your double declaration of ClassATraits<> looks a bit funky too.
typedef Class Some;
后来被用作:
which was later used like:
return Some.funct();
据我所知,这是一个语法错误-您可以通过删除所有模板标签来了解这一点:
Which as far as I can tell is a syntax error - you can see that by getting rid of all the template guff:
class A
{
public:
void f();
};
class B
{
public:
typedef A C;
void g()
{
C.f();
}
};
编译器将在C.f()
行告诉您类似的内容:未在特定对象上未调用非静态成员引用"(或者可能不是(VC ++告诉我在该行之前缺少分号).无论如何,这样做那会告诉您那里存在错误,因此您应该先修复它,然后再对其进行所有模板元编程.
干杯,
灰
PS:似乎我对模板感到沮丧-我没有,只要看到有人潜入而没有真正看到他们的代码在至少一个用例中是否合法,我就感到绝望.
PPS:如果您是自学的,这可能不是您的错.如果您的手肘力量更大!
The compiler will tell you something like: "non-static member reference not called on a specific object" at the line C.f()
(Or maybe not (VC++ tells me that there''s a missing semicolon before the line). Anyway, doing that would have told you there''s an error there so you ought to fix it before going all template meta-programmy on it.
Cheers,
Ash
PS: It may seem I have a downer on templates - I don''t, I just despair whenever I see someone dive in without actually seeing if their code is going to be legal in at least one use case.
PPS: This might not be your fault if you''re self taught. If you are more power to your elbow!
#ifndef DBCONNECTION_H_
#define DBCONNECTION_H_
#include "DBConnectionTraits.h"
template <typename T, typename DBTraits = DBConnectionTraits<T> >
class DBConnection {
typedef DBTraits ConnTraits;
typedef typename DBTraits::Connection Connection;
public:
typedef typename DBTraits::Result Result;
DBConnection():
conn()
{
}
virtual ~DBConnection()
{
}
std::string getDbName()
{
return ConnTraits::getDbName(conn);
}
std::string getHostName()
{
return ConnTraits::getHostName(conn);
}
std::string getPassword()
{
return ConnTraits::getPassword(conn);
}
int getPort()
{
return ConnTraits::getPort(conn);
}
std::string getUserName()
{
return ConnTraits::getUserName(conn);
}
void setDbName(std::string dbName)
{
ConnTraits::setDbName(conn, dbName);
}
void setHostName(std::string hostName)
{
ConnTraits::setHostName(conn, hostName);
}
void setPassword(std::string passwd)
{
ConnTraits::setPassword(conn, passwd);
}
void setPort(int port)
{
ConnTraits::setPort(conn, port);
}
void setUserName(std::string userName)
{
ConnTraits::setUserName(conn, userName);
}
const Result getResult()
{
return ConnTraits::getResult(conn);
}
void disconnect()
{
ConnTraits::disconnect(conn);
}
std::string getOptions()
{
return ConnTraits::getOptions(conn);
}
void setOptions(std::string options)
{
ConnTraits::setOptions(conn, options);
}
void connect()
{
ConnTraits::connect(conn);
}
Result exec(std::string query)
{
return ConnTraits::exec(conn, query);
}
Result exec()
{
return ConnTraits::exec(conn);
}
bool prepare(const std::string query)
{
return ConnTraits::prepare(conn, query);
}
void addBindValue(DBVariant value)
{
ConnTraits::addBindValue(conn, value);
}
Result getData()
{
return ConnTraits::getResult(conn);
}
void close()
{
ConnTraits::close(conn);
}
private:
Connection conn;
};
还有DBConnectionTraits
And the DBConnectionTraits
#ifndef DBCONNECTIONTRAITS_H_
#define DBCONNECTIONTRAITS_H_
#include <iostream>
#include <string>
#include "DBVariant.h"
template <typename T>
struct DBConnectionTraits{
};
#ifdef LIB_PSQL
#include "SQLClasses/PSQL.h"
template <>
struct DBConnectionTraits<PSQL>
{
typedef PSQL Connection;
typedef PSQL::Result Result;
static std::string getDbName(const Connection& conn)
{
return conn.getDbName();
}
static std::string getHostName(const Connection& conn)
{
return conn.getHostName();
}
static std::string getPassword(const Connection& conn)
{
return conn.getPassword();
}
static int getPort(const Connection& conn)
{
return conn.getPort();
}
static std::string getUserName(const Connection& conn)
{
return conn.getUserName();
}
static void setDbName(Connection& conn, std::string dbName)
{
conn.setDbName(dbName);
}
static void setHostName(Connection& conn, std::string hostName)
{
conn.setHostName(hostName);
}
static void setPassword(Connection& conn, std::string passwd)
{
conn.setPassword(passwd);
}
static void setPort(Connection& conn, int port)
{
conn.setPort(port);
}
static void setUserName(Connection& conn, std::string userName)
{
conn.setUserName(userName);
}
static const Result getResult(Connection& conn)
{
return conn.getResult();
}
static void close(Connection& conn)
{
conn.close();
}
static std::string getOptions(const Connection& conn)
{
return conn.getOptions();
}
static void setOptions(Connection& conn, std::string options)
{
conn.setOptions(options);
}
static void connect(Connection& conn)
{
conn.connect();
}
static Result exec(Connection& conn, const std::string query)
{
return conn.exec(query);
}
static Result exec(Connection& conn)
{
return conn.exec();
}
static Result getData(Connection & conn)
{
return conn.getResult();
}
static bool commit(Connection & conn)
{
return conn.commit();
}
static bool prepare(Connection & conn, const std::string query)
{
return conn.prepare(query);
}
static void addBindValue(Connection & conn, DBVariant value)
{
conn.addBindValue(value);
}
static std::string connectOptions(Connection & conn)
{
return conn.getOptions();
}
static std::string lastError(Connection & conn)
{
return conn.getLastError();
}
/*
* Make the query inactive before doing the rollback.
*/
static bool rollback(Connection & conn)
{
return conn.rollback();
}
};
#endif
#ifdef LIB_SQLITE3
#include "SQLClasses/SQLITE3.h"
template <>
struct DBConnectionTraits<SQLITE3>
{
typedef SQLITE3 Connection;
typedef SQLITE3::Result Result;
static std::string getDbName(const Connection& conn)
{
return conn.getDbName();
}
static std::string getHostName(const Connection& conn)
{
return conn.getHostName();
}
static std::string getPassword(const Connection& conn)
{
return conn.getPasswd();
}
static int getPort(const Connection& conn)
{
return conn.getPort();
}
static std::string getUserName(const Connection& conn)
{
return conn.getUserName();
}
static void setDbName(Connection& conn, std::string dbName)
{
conn.setDbName(dbName);
}
static void setHostName(Connection& conn, std::string hostName)
{
conn.setHostName(hostName);
}
static void setPassword(Connection& conn, std::string passwd)
{
conn.setPasswd(passwd);
}
static void setPort(Connection& conn, int port)
{
conn.setPort(port);
}
static void setUserName(Connection& conn, std::string userName)
{
conn.setUserName(userName);
}
static const Result getResult(Connection& conn)
{
return conn.getLastResult();
}
static void close(Connection& conn)
{
conn.close();
}
static std::string getOptions(const Connection& conn)
{
return conn.getOptions();
}
static void setOptions(Connection& conn, std::string options)
{
conn.setOptions(options);
}
static void connect(Connection& conn)
{
conn.connect();
}
static Result exec(Connection& conn, const std::string query)
{
return conn.exec(query);
}
static Result exec(Connection& conn)
{
return conn.exec();
}
static Result getData(Connection & conn)
{
return conn.getLastResult();
}
static bool commit(Connection & conn)
{
return conn.commit();
}
static bool prepare(Connection & conn, const std::string query)
{
return conn.prepare(query);
}
static void addBindValue(Connection & conn, DBVariant value)
{
conn.addBindValue(value);
}
static std::string connectOptions(Connection & conn)
{
return conn.getOptions();
}
static std::string lastError(Connection & conn)
{
return conn.getLastError();
}
/*
* Make the query inactive before doing the rollback.
*/
static bool rollback(Connection & conn)
{
return conn.rollback();
}
};
#endif
#endif /* DBCONNECTION_H_ */
我想要这个
And i want this
#include "DBConnection.h"
template <typename typebd="">
class Executor {
typedef DBConnection<typebd>::Result Result; //<-- This is the error
public:
Result execSomething ();
}
</typebd></typename>
对于分隔,DBConnection可以正常工作,但使用typedef BUMM即可!!!
For separated, the DBConnection work fine, but with the typedef, BUMM!!!
这篇关于实例一个类模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!