下面的代码中,为什么模板函数的显式扩展foo无法编译,而 的扩展却bar编译成功?实时链接 - https://godbolt.org/z/o8Ea49KEb
template <typename T1, typename T2>\nT1 foo(T2) { T2(42); return T1{}; };\n\ntemplate <typename T1, typename T2>\nT1 bar(void) { T2(42); return T1{}; };\n\nint main()\n{\n foo<int, void>(); // fails\n\n bar<int, void>(); // works\n}\nRun Code Online (Sandbox Code Playgroud)\nT2请注意,两个函数的主体中都使用了模板参数,唯一的区别是函数参数 tobar已被手动替换。
这个问题是在阅读std::conditional - Invalid argument type \xe2\x80\x98void\xe2\x80\x99 即使在测试 \'void\'并试图简化问题时受到启发的。
\n尝试获取两个回调的签名并生成使用它们每个返回值的回调签名。
\n\n给定回调A并B=> 生成F
例 1) A: int(char)B: double(bool)=> F: double(int)
例 2) A: void(char)B: void(int)=> F: void(void)
void使用参数实例化回调时遇到奇怪的编译器错误:
error: invalid parameter type \xe2\x80\x98void\xe2\x80\x99
template<class Signature>\nstruct my_func;\n\ntemplate<class Ret, class... Args>\nstruct my_func<Ret(Args...)>\n{};\n\ntemplate<class FuncA, class FuncB>\nstruct my_fwd;\n\ntemplate<class ORet, class... OArgs,\n class Ret, class... Args>\nstruct my_fwd<\n my_func<ORet(OArgs...)>,\n my_func<Ret(Args...)>\n >\n{\n my_func< ORet(Ret) > func; // <--- error\n};\n\nint main(int, char *[])\n{\n my_func<void(int)> my3; // (1)\n my_func<void(void)> my4; // …Run Code Online (Sandbox Code Playgroud)