【发布时间】:2015-09-11 20:59:36
【问题描述】:
我正在尝试使用 SFINAE 创建一个带有模板重载方法的模板类,以排除未使用的方法,但在阅读了许多帖子和数小时的工作后,我不知道哪个是我的错误。
我的想法是创建一个有 4 个参数的类模板,其中 3 个是可选参数,其中 2 个可选参数将在重载方法中使用,并且只会编译正确的版本,就像这样(对不起,我尝试使用语法高亮,但我不知道怎么做)
template<char const q[], typename P1 = void, typename P2 = void, typename P3 = void>
class query
{
char const * const value;
public:
query() : value(q) {};
template<typename returnType, something else>
returnType execute(P1 data1, P2 data2) { ..... };
template<typename returnType, something else>
returnType execute(P2 data2) { ..... };
template<typename returnType, something else>
returnType execute(P1 data1) { ..... };
template<typename returnType, something else>
returnType execute() { ..... };
}
constexpr char const q_str[] = "hola mundo";
class A {};
int main()
{
query<q_str> v1;
query<q_str, A> v2;
A param;
bool rc = v2.execute<bool>(param); << I expect to use the method execute(P1 data1)
return 0;
}
所以,我的代码是这样的
template<char const q[], typename Tin = void, typename Tout = void, typename Twhere = void>
class query
{
char const * const value;
public:
typedef Tin ty_bind_in;
typedef Tout ty_bind_out;
query() : value(q) {};
template<typename returnType,
typename in = Tin,
typename cond = typename std::enable_if< std::is_class<in>::value, void >::type>
returnType execute(Tin &p_data)
{
returnType rs;
return rs;
};
template<typename returnType>
returnType execute()
{
returnType rs;
return rs;
};
};
constexpr char const q_str[] = "hola mundo";
class A {};
int main()
{
query<q_str, A> q1;
query<q_str> q2;
return 0;
}
我正在使用这个版本的 gcc
gcc (Debian 4.9.2-10) 4.9.2
我要编译的行是这样的
g++ -std=c++11 -g stack.cpp
我得到这个错误
stack.cpp: In instantiation of ‘class query<((const char*)(& q_str))>’:
stack.cpp:40:15: required from here
stack.cpp:19:13: error: forming reference to void
returnType execute(Tin &p_data)
^
如您所见,我一声明变量就会收到错误消息。可能我做错了什么,但我不知道问题出在哪里。
编辑 14/09: 再次嗨,在 Barry 的解释之后,我解决了这个问题并继续我的想法,所以我尝试为方法执行添加两个重载,第一个是这个(想法:当模板参数 Tin 和 Twhere 为 != void 时,此方法将起作用)
template<typename returnType,
typename in = Tin,
typename cond2 = typename std::enable_if<std::is_class<in>::value >::type,
typename where = Twhere,
typename cond = typename std::enable_if< std::is_class<where>::value >::type>
returnType execute(in &p_data, where &p_where)
{
returnType rs;
return rs;
};
第二个是this(想法:当模板参数Twhere为!= void时,此方法将起作用)
template<typename returnType,
typename where = Twhere,
typename cond = typename std::enable_if< std::is_class<where>::value >::type>
returnType execute(where &p_data)
{
returnType rs;
return rs;
};
我收到以下错误
stack.cpp:39:13: error: ‘template<const char* q, class Tin, class Tout, class Twhere> template<class returnType, class where, class cond> returnType query<q, Tin, Tout, Twhere>::execute(where&)’ cannot be overloaded
returnType execute(where &p_data)
^
stack.cpp:19:13: error: with ‘template<const char* q, class Tin, class Tout, class Twhere> template<class returnType, class in, class cond> returnType query<q, Tin, Tout, Twhere>::execute(in&)’
returnType execute(in &p_data)
在我看来,这是因为 Tin 和 Twhere 的重载版本在参数方面看起来相等,但我不知道如何更正代码。
一些想法?
提前谢谢你 最好的问候
【问题讨论】:
-
您的第一个代码块是否与问题相关?你介意我把它删掉吗?
-
嗨,Barry,我的第一个代码块只是一个例子来说明我的意图,因为我的真实代码可能有错误,实际上可能有错误
标签: c++ templates overloading sfinae