簡體   English   中英

標准對這個指向成員函數類型的模板參數有什么看法? 我的代碼是錯誤的,還是 MSVS 16.6 有問題?

[英]What does the standard say about this pointer-to-member-function type template parameter? Is my code wrong, or is MSVS 16.6 buggy?

下面是一些適用於 GCC、Clang 和 MSVS 的代碼(至少,那些當前在 Compiler Explorer 上可用的版本):

template <typename T, auto T::* MemberPtr>
struct Foo
{
    Foo(const T& e) : _e(e) {}

    void operator()() const
    {
        (_e.*MemberPtr)();
    }

private:
    const T& _e;
};

struct Bar
{
    void baz() const {}

    auto bind()
    {
        using BindingType = Foo<Bar, &Bar::baz>;
        return BindingType(*this);
    }
};

int main()
{
    Bar i;
    i.bind();
}

但是,從 v16.6.1 開始,MSVS 拒絕了它:

Severity  Code   Description                                                                      Line
Error     C2973  'Foo': invalid template argument 'int'                                           23
Error     E2886  cannot deduce 'auto' template parameter type "auto T::*" from "void (Bar::*)()"  21
Error     C2440  'specialization': cannot convert from 'overloaded-function' to 'auto Bar::* '    22
Error     C3535  cannot deduce type for 'auto Bar::* ' from 'int'                                 23
Error     C2440  'specialization': cannot convert from 'int' to 'int Bar::* '                     23

通過取出MemberPtrT::*限定符,可以在該版本中“修復”代碼; 所以:

template <typename T, auto MemberPtr>

標准對此有何評論? VS v16.6.1 是引入了新的回歸,還是現在診斷出總是被巧妙地破壞的代碼?

參數/參數組合按原樣有效

[溫度參數]

4非類型模板參數應具有以下類型之一(可選 cv 限定):

  • ...
  • 包含占位符類型的類型。

[temp.arg.nontype]

1如果模板參數的類型包含占位符類型,則推導的參數類型由模板參數的類型通過占位符類型推導確定。 如果模板參數聲明([temp.param])不允許推導參數類型,則程序格式錯誤。

現在, auto T::*是一種包含占位符類型的類型。 並且 占位符類型推導在表單中的變量聲明中工作得很好

auto Bar::* foo = &Bar::baz;

所以 VS v16.6.1 沒有拒絕這種非類型模板參數的業務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM