c++ - 为什么此代码片段适用于 C++17,而编译器在使用 C++11 时会报错?
问题描述
为什么这个代码片段适用于 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,而以前只允许函数的实际名称。
推荐阅读
- python - 错误值的长度 (1) 与索引的长度 (300) 不匹配
- sql - postgresql 中的传递连接
- python - Python 按列分组并在所有其他列上按 value_counts
- html - 按水平顺序放置引导卡
- excel - 只有在excel中有一个时才删除中间的首字母
- scala - Apache Spark 异常:FileAlreadyExistsException:操作失败:“指定的路径已存在。”
- json - 如何在 swift 5 中访问和传递 HealthKit 数据导致一个函数来自另一个函数,以便在 urlSession 中进行 JSON 序列化?
- python - 如何将值解析为日期时间?
- r - 在 RStudio 中进行分析 - profvis() 未提供所需的输出
- c - 如何计算玻璃汁的体积?