gpt4 book ai didi

c++ - 与模板类型相关的编译时错误发生在理论上不会发生的地方

转载 作者:搜寻专家 更新时间:2023-10-31 00:34:27 26 4
gpt4 key购买 nike

我有一个模板函数 template<class T> T exc(T())其中 T 有时可以为空。

此函数用于执行函数并返回值(如果它不为空)。

这是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;});

如您所知,strcmp返回 0什么时候typeid(T).name()等于 "void" .

也就是说runtime理论上是没有问题的。然而,这是错误的

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 情况下显式声明模板参数,特化可以做到这一点,但请注意 to some overloading vs specialization resolutions)。

最后你还可以返回一个void调用

void fun() {}

template <class T>
T exc(T (*func)()) {
return func();
}

exc<void>(fun);

要记住的一件事是,在编译模板代码时,所有范围内的分支都应该在任何时候都有效。如果模板类型不匹配,则 if 分支不会神奇地“消除死代码”——它会产生错误。

关于c++ - 与模板类型相关的编译时错误发生在理论上不会发生的地方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26085463/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com