组合模板参数形成函数签名时无效的 void 参数
Invalid void parameter when combining template parameters to form a function signature
尝试获取两个回调的签名并生成使用其每个返回值的回调签名。
给定回调A
和B
=> 生成F
例 1)A:int(char)
B:double(bool)
=> F: 双精度(整数)
例 2)答:void(char)
乙:void(int)
=> 女:空(空)
在实例化以void
作为参数的回调时遇到了一个奇怪的编译器错误:
error: invalid parameter type ‘void’
有问题的代码
template<class Signature>
struct my_func;
template<class Ret, class... Args>
struct my_func<Ret(Args...)>
{};
template<class FuncA, class FuncB>
struct my_fwd;
template<class ORet, class... OArgs,
class Ret, class... Args>
struct my_fwd<
my_func<ORet(OArgs...)>,
my_func<Ret(Args...)>
>
{
my_func< ORet(Ret) > func; // <--- error
};
int main(int, char *[])
{
my_func<void(int)> my3; // (1)
my_func<void(void)> my4; // (2)
my_func<void()> my5; // (3)
my_fwd< decltype(my3), my_func<void(char)> > fwd1; // (4)
my_fwd< decltype(my3), decltype(my4) > fwd2; // (5)
return 0;
}
虽然my_func
的实例化没有问题,void
(1), (2), (3)
,my_fwd
(4) (5)
失败,我想了解原因。
解决方法?!
我找到了一种解决方法,通过专门针对Ret == void
my_fwd
:
// with this specialization i can avoid the error
template<class ORet, class... OArgs,
class... Args>
struct my_fwd<
my_func<ORet(OArgs...)>,
my_func<void(Args...)>
>
{
my_func< ORet() > func;
};
问题
编译器尝试在内部实例化有什么区别
my_fwd< my_func<void(int)>, my_func<void(char)> >
:
->my_func<void(void)> func
和
main(): 中的手动版本my_func<void(void)> my4
?
void
专用化是修复的正确方法吗? 选择? 我显然对专业化和代码重复并不感兴趣。
将void
作为模板参数与手动编写void (void)
之间的区别在于,后者不会生成采用void
参数的函数。将(void)
列为函数的参数是一种语法结构,其含义与()
相同。这是 C 的遗留问题,其中()
表示"参数未指定",(void)
表示"没有参数"。C++删除了未指定的情况,()
在那里表示"没有参数"。
但是,模板实例化发生在语法处理之后很长时间,因此实际上尝试实例化函数的参数(T)
T = void
会导致错误。就像尝试声明一个函数需要(std::remove_reference<decltype(std::declval<void*>())>::type)
(即void
实际上拼写为一种类型)。
恐怕你能解决这个问题的唯一方法确实是专门针对void
。
- std::cin >>上的参数无效
- 结果失败或多个参数无效
- 错误:一元"*"的类型参数无效(具有"int"):使用 mergesort 计算
- 错误 带有模块的一元"*"(具有"int")的类型参数无效
- 由于调用 std::condition_variable 后参数无效而导致应用程序崩溃
- MPI_Iprobe:RMA 调用中的位移参数无效
- 推力::sort_by_key上的配置参数无效
- windres 致命错误:将输出写入时:参数无效
- 一元'*'的类型参数无效(有双精度)
- C++:传递给 C 运行时函数的参数无效
- 矢量模板参数无效
- 写入 -: 参数无效 } 时出错
- winsock2:recvfrom()函数以错误10022(参数无效)结束
- 模板参数的显式指定参数无效,该参数是 constexpr
- 模板参数无效
- 调用 getter 成员时的参数无效
- 模板模板参数中的参数无效
- 方法调用中的参数无效
- POSIX 计时器:参数无效
- C++类模板是一个模板:模板参数无效