可以将包含函数指针的类用作非类型模板参数吗? [英] Can a class containing a function pointer be used as a non-type template parameter?

查看:72
本文介绍了可以将包含函数指针的类用作非类型模板参数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下包含函数指针的类 S 和该类的以lambda初始化的 constexpr 对象 s :

Consider the following class S containing a function pointer, and a constexpr object s of that class initialized with a lambda:

struct S 
{ 
    void (*f) (); 
};

constexpr S s { []{} };

现在,如果我编写一个类型为 S 的非类型模板参数的模板 X ,并通过 s 实例化它,如下所示:

Now if I write a template X with a non-type template parameter of type S, and instantiate it over s like this:

template<S> struct X {};
using x = X<s>;

clang编译代码,但是gcc抱怨:

clang compiles the code, but gcc complains with:

error: '<lambda()>::_FUN' is not a valid template argument of type 'void (*)()' because '<lambda()>::_FUN' is not a variable
using x = X<s>;
             ^

这是程序.

代码对我来说似乎很好,而且我不确定错误消息指的是什么.这段代码有效吗?

The code seems fine to me, and I'm not sure what the error message is referring to. So is this code valid?

请注意,如果 X 具有引用类型为 S 的非类型模板参数,则两个编译器均接受该代码,如下所示:

Note that both compilers accept the code if X instead has a non-type template parameter of reference type to S, like this:

template<S const &> struct X {};


这个问题的灵感来自另一个类似的问题.

推荐答案

该代码有效.

[temp.arg.nontype]/2 :

非类型 template-parameter template-argument 应该是类型的转换后的常量表达式([expr.const]).模板参数.

[expr.const]/10 :

类型为 T 转换后的常量表达式是一个隐式转换为类型 T 的表达式,其中转换后的表达式为常量表达式,隐式转换序列仅包含[...]

A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant expression and the implicit conversion sequence contains only [...]

(在这种情况下,没有隐式转换.)

(There's no implicit conversion in this case.)

[expr.const]/11 :

一个常量表达式是[...]或一个prvalue核心常量表达式,其值满足以下约束:

A constant expression is [...] or a prvalue core constant expression whose value satisfies the following constraints:

  • 如果该值是类类型的对象,则每个引用类型的非静态数据成员都引用一个实体,该实体是常量表达式的允许结果,
  • 如果该值是指针类型,则它包含[...]非立即函数的地址[...],
  • 如果该值是指向成员函数类型的指针,[...],
  • 如果值是类或数组类型的对象,则每个子对象都满足该值的这些约束.

如果[...]或它是非立即函数,则实体是常量表达式的允许结果.

An entity is a permitted result of a constant expression if [...] or if it is a non-immediate function.

(除了 consteval 功能之外,所有功能都不是直接的.

(All functions are non-immediate except for the consteval ones. [dcl.constexpr])

因此, s 是类型为 S 的有效转换常量表达式.此外,它不受 [temp.arg.nontype]/3的约束(仅适用于对象的指针/引用).

Therefore, s is a valid converted constant expression of type S. In addition, it is not subject to [temp.arg.nontype]/3 (which only applies to pointer/reference to objects).

也就是说, s 是有效的模板参数.

That is, s is a valid template argument.

我不确定错误消息指的是什么

I'm not sure what the error message is referring to

这是胡说八道.

<代码在GCC中> invalid_tparm_referent_p .它是从实现类非类型模板参数时处理对象类型指针的代码中提取的( 4be5c72 ).显然,实现者忘记了更新此功能以解决指针指向功能的情况.

The error is emitted from invalid_tparm_referent_p inside GCC. It was extracted from code for handling pointer to object type when class non-type template paramter was implemented (4be5c72). Apparently, the implementer forgot to update this function to account for the pointer-to-function case.

我将错误报告为 https://gcc.gnu.org/PR97700 .

这篇关于可以将包含函数指针的类用作非类型模板参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆