具有不同指向成员指针的参数的非类型模板参数的特化是否保证是唯一的特化?

Are specializations over a non-type template parameter with an argument of different pointer-to-members guaranteed to be unique specializations?

考虑以下 class 模板:

template <auto>
struct T {};

(1) 指向数据成员或指向成员函数的指针。


或者,应用于以下示例:

struct S {
    int x;
    int y;
    void f();
    void g();
};

static_assert(std::is_same_v<decltype(&S::x), decltype(&S::y)>);
static_assert(std::is_same_v<decltype(&S::f), decltype(&S::g)>);

或者,在代码中,以下片段是否格式正确?

// T and S as above.
static_assert(!std::is_same_v<T<&S::x>, T<&S::y>>);
static_assert(!std::is_same_v<T<&S::f>, T<&S::g>>);

以下所有标准参考均参考 N4659: March 2017 post-Kona working draft/C++17 DIS


是的,它们肯定指的是不同的专业。

根据[temp.names]/1

[temp.names]/1 A template specialization can be referred to by a template-id: [...]

模板专业化由 template-id 正式引用,并且根据 [temp.type]/1, which governs type equivalence, particularly [temp.type]/1.5 [emphasis 我的]

[temp.type]/1 Two template-ids refer to the same class, function, or variable if

  • /1.1 their template-names, operator-function-ids, or literal-operator-ids refer to the same template and
  • [...]
  • /1.5 their corresponding non-type template-arguments of pointer-to-member type refer to the same class member or are both the null member pointer value and [...]

不申请 template-id 如果它们的非类型 template-arguments 指向成员类型引用不同 class 成员相同class(模板)。

为例
static_assert(!std::is_same_v<T<&S::x>, T<&S::y>>);
static_assert(!std::is_same_v<T<&S::f>, T<&S::g>>);

特别是,[temp.type]/1.1 适用并已实现,而/1.5 适用且未实现([temp.type]/1 的其余段落在此不适用)。

理论上是的。实际上,考虑

union A {
    int foo;
    int bar;
};
template<auto>
struct T{};

MSVC 将 T<&A::foo>T<&A::bar> 视为同一类型。