gpt4 book ai didi

c++ - 为什么将 lambda 用于非类型模板参数时 gcc 会失败?

转载 作者:IT老高 更新时间:2023-10-28 22:30:19 26 4
gpt4 key购买 nike

以下片段 compiles Clang 4.0 没有错误,但 GCC 7.0 产生 errors (注意使用 -std=c++1z 标志)。

using FuncT = int (*)(double);

template <FuncT FUNC>
int temp_foo(double a)
{
return FUNC(a);
}

int foo(double a)
{
return 42;
}

void func()
{
auto lambda = [](double a) { return 5; };

struct MyStruct
{
static int foo(double a) { return 42; }
};

temp_foo<foo>(3);
temp_foo<static_cast<FuncT>(lambda)>(3);
temp_foo<MyStruct::foo>(3);
}

具体来说,GCC 提示 lambda 和嵌套类的方法都没有链接,因此它们不能用作非类型模板参数。

至少对于 lambda 情况,我认为 Clang 是正确的(而 GCC 是错误的),因为(引用 cppreference ,转换运算符):

The value returned by this conversion function is a pointer to a function with C++ language linkage that, when invoked, has the same effect as invoking the closure object's function call operator directly.

GCC 是否行为不端?

最佳答案

根据http://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter ,似乎自 C++17 以来不再需要外部链接。在 C++17 草案中的 [temp.arg.nontype] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf 下可以找到相同的语言。 (请注意,它被错误地链接为 C++14 草案)。

The template argument that can be used with a non-type template parameter can be any converted constant expression of the type of the template parameter...

The only exceptions are that non-type template parameters of reference and pointer type cannot refer to/be the address of

  • a subobject (including non-static class member, base subobject, or array element);
  • a temporary object (including one created during reference initialization);
  • a string literal;
  • the result of typeid;
  • or the predefined variable __func__.

cppreference 上的那个链接还特别提到了 C++ 17 之前的函数指针:

The following limitations apply when instantiating templates that have non-type template parameters:

...

For pointers to functions, the valid arguments are pointers to functions with linkage (or constant expressions that evaluate to null pointer values).

由于您的问题被标记为 C++1z(我们现在可能应该有一个 17 标记并使用它,因为 17 已经完成)我们应该使用第一组规则。您的示例似乎不属于 C++ 17 的任何异常类别,因此 gcc 是错误的。

请注意,如果您将语言标志更改为 14,clang 不会编译您的示例。

关于c++ - 为什么将 lambda 用于非类型模板参数时 gcc 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43213997/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com