我可以将 C++17 无捕获 lambda constexpr 转换运算符的结果用作函数指针模板非类型参数吗?
Posted
技术标签:
【中文标题】我可以将 C++17 无捕获 lambda constexpr 转换运算符的结果用作函数指针模板非类型参数吗?【英文标题】:Can I use the result of a C++17 captureless lambda constexpr conversion operator as a function pointer template non-type argument? 【发布时间】:2018-05-16 08:25:39 【问题描述】:在回答 How do I write a lambda expression that looks like a method? 时,我尝试利用以下事实将无捕获 lambda 转换为成员函数指针:自 C++17 以来,无捕获 lambda 对其函数有一个 constexpr 转换运算符指针类型。
所以我想出了一个归结为:
template<void(*)()> struct A;
int main()
A<static_cast<void(*)()>([])>; // 1
constexpr auto fp = static_cast<void(*)()>([]);
A<fp>; // 2
现在,它在 clang 中编译(从 5.0.0 开始)但 gcc(>=7.2) 抱怨:
error: lambda-expression in template-argument
A<static_cast<void(*)()>([] /*whatever*/ )>; // 1
^
error: 'main()::<lambda()>::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::<lambda()>::_FUN()' has no linkage
A<fp>; // 2
问题是,谁是对的?
【问题讨论】:
应该有一个使用 constexpr 局部变量的更简单的例子,不是吗? @Yakk,完成;这并不完全等同于原始代码......还是不? 我不禁想知道您到底想做什么以及为什么需要这样做。 指向没有链接的函数的指针应该被允许在 C++17 中作为非类型模板参数。见N4198。 @massim 不太一样,但简单了 3 倍。我可以看到用途;尽可能快地委托便携式版本。 【参考方案1】:这是一个 gcc 错误,已提交 83258。
在 C++14 中,我们曾经有一个 linkage requirement 用于指针类型的非类型模板参数。但是在 C++17 中(作为N4268 的结果),参数只需要是正确类型的converted constant expression,还有一些其他限制(这里都不相关)。一旦我们可以构造fp
,我们应该能够将它用作模板参数。
【讨论】:
以上是关于我可以将 C++17 无捕获 lambda constexpr 转换运算符的结果用作函数指针模板非类型参数吗?的主要内容,如果未能解决你的问题,请参考以下文章