我正在编写一个与std::function
(或至少这些类在许多方面相似)共享几个不同功能的类。大家都知道std::function
是通过指定模板参数(即std::function<void (std::string&)>
)来实例化的,我的类也是一样。不过我有一个例外,如果返回值为 void ( ) ,我想在我的类中专门化一个函数。std::function<"return value" ("parameters">
我需要在编译时完成此操作,但我无法使其正常工作。以下是一些解释的测试代码:
#include <iostream>
#include <type_traits>
template <typename T> class Test { };
template <typename Ret, typename... Args>
class Test<Ret (Args...)>
{
public:
Ret operator()(Args...)
{
if(std::is_void<Ret>::value)
{
// Do something...
}
else /* Not a void function */
{
Ret returnVal;
return returnVal;
}
}
};
int main(int argc, char * argv[])
{
Test<void (char)> test;
test('k');
}
如您所见,如果编译器在上述测试中没有删除“else”分支,我的代码将尝试创建一个 void 值(即void returnVal;
)。问题是编译器没有删除分支所以我最终得到一个编译器错误:
./test.cpp: 在 'Ret Test::operator()(Args ...) [with Ret = void; Args = {char}]': ./test.cpp:27:10: 从这里需要 ./test.cpp:18:8: 错误:变量或字段“returnVal”声明为无效 ./test.cpp:19:11 :错误:带有值的返回语句,在函数返回'void'[-fpermissive]
通常会使用std::enable_if
with std::is_void
,问题是我不想专注于函数模板,而是专注于类模板。
template <typename Ret, typename... Args>
class Test<Ret (Args...)>
{
public:
typename std::enable_if<!std::is_void<Ret>::value, Ret>::type
Ret operator()(Args...)
{
Ret returnVal;
return returnVal;
}
typename std::enable_if<std::is_void<Ret>::value, Ret>::type
Ret operator()(Args...)
{
// It's a void function
// ...
}
};
如果我改用上面的代码,我最终会遇到更多错误并且没有解决方案
./test.cpp:11:2: error: expected ‘;’ at end of member declaration
./test.cpp:11:2: error: declaration of ‘typename std::enable_if<(! std::is_void<_Tp>::value), Ret>::type Test<Ret(Args ...)>::Ret’
./test.cpp:6:11: error: shadows template parm ‘class Ret’
./test.cpp:11:24: error: ISO C++ forbids declaration of ‘operator()’ with no type [-fpermissive]
./test.cpp:18:2: error: expected ‘;’ at end of member declaration
./test.cpp:18:2: error: declaration of ‘typename std::enable_if<std::is_void<_Tp>::value, Ret>::type Test<Ret(Args ...)>::Ret’
./test.cpp:6:11: error: shadows template parm ‘class Ret’
./test.cpp:18:24: error: ISO C++ forbids declaration of ‘operator()’ with no type [-fpermissive]
./test.cpp:18:6: error: ‘int Test<Ret(Args ...)>::operator()(Args ...)’ cannot be overloaded
./test.cpp:11:6: error: with ‘int Test<Ret(Args ...)>::operator()(Args ...)’
./test.cpp: In member function ‘int Test<Ret(Args ...)>::operator()(Args ...)’:
./test.cpp:22:2: warning: no return statement in function returning non-void [-Wreturn-type]
./test.cpp: In instantiation of ‘int Test<Ret(Args ...)>::operator()(Args ...) [with Ret = void; Args = {char}]’:
./test.cpp:28:10: required from here
./test.cpp:13:7: error: variable or field ‘returnVal’ declared void
./test.cpp: In member function ‘int Test<Ret(Args ...)>::operator()(Args ...) [with Ret = void; Args = {char}]’:
./test.cpp:15:2: warning: control reaches end of non-void function [-Wreturn-type]
对不起,如果我只是愚蠢的,答案是显而易见的。我对模板相当陌生,在任何其他线程/问题中都找不到合适的答案。