加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 在模板中转换成员函数指针

发布时间:2020-12-16 03:27:33 所属栏目:百科 来源:网络整理
导读:假设我有以下两个类: templatetypename Tstruct Base{ void foo();};struct Derived : BaseDerived {}; 我可以做这个: void (Derived::*thing)() = Derived::foo; 编译器很高兴(正如我所料). 当我把它放在两个级别的模板中时突然爆炸: templatetypename T
假设我有以下两个类:
template<typename T>
struct Base
{
    void foo();
};

struct Derived : Base<Derived> {};

我可以做这个:

void (Derived::*thing)() = &Derived::foo;

编译器很高兴(正如我所料).

当我把它放在两个级别的模板中时突然爆炸:

template<typename T,T thing>
struct bar {};

template<typename T>
void foo()
{
    bar<void (T::*)(),&T::foo>{};
}

int main()
{
    foo<Derived>();  // ERROR
    foo<Base<Derived>>(); // Works fine
}

这失败了:

non-type template argument of type 'void (Base<Derived>::*)()' cannot be converted to a value of type 'void (Derived::*)()'

godbolt

为什么简单的案例工作而更复杂的案例失败了?我相信这与this问题有关,但我并不完全确定….

解决方法

@YSC钉出了& Derived :: foo;的类型.既然你想知道为什么这个隐式转换……
void (Derived::*thing)() = &Derived::foo;

…飞行正常但不在模板中,原因如下:

[temp.arg.nontype]

07001 A template-argument for a non-type template-parameter shall be a
converted constant expression of the type of the template-parameter.

[expr.const]

07002 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

  • […]

我省略的列表不包含pointer to member conversions.因此,使该模板参数对您指定的参数无效.

一个简单的解决方法是使用decltype(& T :: foo)而不是void(T :: *)()作为类型参数.这是一个结构良好的替代品:

bar<decltype(&T::foo),&T::foo>{};

无论是否可接受,当然取决于您的用例,超出了MCVE的范围.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读