为什么此代码段适用于C ++ 17,而编译器在使用C ++ 11时会抱怨(即https://godbolt.org/z/71G91P)?此代码段是否存在任何潜在问题?
#include<iostream>
class ctx
{
public:
int map_create(void*){std::cout << "haha" << std::endl; return 0;};
};
ctx obj;
typedef int (ctx::*ctx_mem_func)(void*);
template <ctx_mem_func func>
int regHelper(void*)
{
((&obj)->*func)(nullptr);
return 0;
}
constexpr ctx_mem_func testFunc = &ctx::map_create;
typedef int(*callBackFunc)(void*);
int reg(callBackFunc)
{
return 0;
}
int main()
{
reg(regHelper<testFunc>);
//But this expression is ok.
reg(regHelper<&ctx::map_create>);
std::cout << "this is a test" << std::endl;
}
这是使用c ++ 11(gun 10.0.2)时的错误消息:
<source>: In function 'int main()':
<source>:30:28: error: no matches converting function 'regHelper' to type 'callBackFunc {aka int (*)(void*)}'
reg(regHelper<testFunc>);
^
<source>:13:5: note: candidate is: template<int (ctx::* func)(void*)> int regHelper(void*)
int regHelper(void*)
^
这是C ++ 14和C ++ 17之间的区别。简化:
int f();
template<int (&)()> struct S {};
constexpr auto& q = f;
using R = S<q>; // valid in C++17, invalid in C++14
更改是允许对所有非类型模板参数进行常量求值,这意味着现在允许constexpr
命名函数(成员函数等)的变量作为NTTP,而以前只允许使用函数的实际名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句