与模板类型相关的编译时错误发生在理论上不发生的地方
template-type-related compile time error occur where theoretically not
我有一个模板函数template<class T> T exc(T())
,其中T有时可能是void。
此函数用于执行一个函数并返回值(如果不是void)。
这是exc
的简化内容(当然我有其他内容=p)
template<class T> T exc(T (*func)()){
if(strcmp(typeid(T).name(), "void")){
T obj = (*func)();
// there are something to do with obj
return obj;
} else{
(*func)();
}
}
// in main:
exc<void>([]() -> void{std::cout << "I'm too lazy to type another function"
<< " so I use lambda" << std::endl;});
如您所知,当typeid(T).name()
等于"void"
时,strcmp
返回0
。
也就是说,运行时在理论上没有问题。然而,这是错误
error C2182 : illegal use of type 'void'
我使用MSVC cl命令行编译器,我认为问题可能是由编译器引起的,该编译器将调用函数的每个模板类型替换为T,因此在T obj
时,会出现错误。
我想问一下,有没有其他解决方案?有没有其他方法可以声明obj,以便编译器将其视为"正确"?还是应该用void exc(void (*func)())
覆盖exc?
如果您的"实际代码"对模板化类型做了更多的处理,那么重载就是答案
template<class T> T exc(T (*func)()){
T obj = (*func)();
// there's something to do with obj
return obj;
}
void exc(void (*func)()){
// something to do with void?
(*func)();
}
(无论如何,在void
的情况下,您将无法显式声明模板参数,专业化可以做到这一点,但要注意一些重载与专业化的解决方案)。
最后,您还可以返回一个void
呼叫
void fun() {}
template <class T>
T exc(T (*func)()) {
return func();
}
exc<void>(fun);
需要记住的一点是,在编译模板化代码时,所有范围内分支在任何时候都应该是有效的。如果模板化的类型不匹配,则if分支不会神奇地"消除死代码"——它会产生错误。
只需执行:
template <class T>
T exc(T (*func)()) {
return func();
}
您可以从void函数中return
为void
类型的表达式。
编辑:如果您需要对obj
应用特殊处理,请不要专门化您的函数模板。过载:
void exc(void (*func)()) {
func();
}
您有错误,因为这两个分支必须是有效的并且
if(strcmp(typeid(T).name(), "void")){
T obj = (*func)();
// there are something to do with obj
return obj;
}
对于T == void
无效(即使不采取分支)
您可以使用过载来解决您的问题:
template<class T> T exc(T (*func)()){
T obj = (*func)();
// there are something to do with obj
return obj;
}
void exc(void (*func)()){
(*func)();
}
相关文章:
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- gcc:"在Windows上编译时找不到-lasound"
- 如何在常量计算表达式中获取编译时错误?
- 仅在使用 gradle 在 Travis CI 上编译时才"multiple definition" googletest 符号
- C++根据调用的构造函数强制编译时错误
- 使用 std::iterator_traits<> 时编译时错误不明确
- is_same和variadic模板编译时错误无效转换
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 引发编译时错误
- 为什么调用不明确的 ctor 时没有编译时错误?
- 在 sizeof 运算符上强制编译时错误
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 从Mac上的终端编译时C 错误
- 使用MINGW-W64使用-M32选项(32位代码)编译时错误
- C++线程错误 - 带有类参数的编译时错误
- 在Visual Studio 2017 Community Edition上编译时,带有QT 5.8的错误C3615
- 在我的 Mac 上编译时,当我使用 "gcc" 而不是使用 clang++ 进行编译时出现此错误
- 与模板类型相关的编译时错误发生在理论上不发生的地方
- Boost signals.hpp在Visual Studio 2010上导致几个编译时错误