【问题标题】:Injected class name as type注入的类名作为类型
【发布时间】:2018-07-31 20:26:48
【问题描述】:

给定以下代码,

template <class> using void_t = void;
template <class C, class = void> struct X { enum { v = 0 }; };
template <class C> struct X<C, void_t<typename C::T> > { enum { v = 1 }; };
struct T { };
int main() { return X<T>::v; }

main 应该返回什么? GCC 和 MSVC 说 1,Clang 说 0。

【问题讨论】:

  • 整洁的角盒。换句话说:注入的类名是否表现得像一个实际的 typedef?
  • 这个问题来自于透明的比较器,类定义了一个名为is_transparent的类型成员。 struct is_transparent { }; 透明吗?当编译器不同意时,我们感到很惊讶。
  • 一个恰当的问题会列出并解释一段神秘代码的可能解释。
  • @n.m. language-lawyer 关于哪个编译器正确的问题与其说是对代码的解释,不如说是对标准的解释。

标签: c++ language-lawyer c++17


【解决方案1】:

我认为 Clang 就在这里。 [class.qual] 中的规则是:

在不忽略函数名称且 nested-name-specifier 指定类 C 的查找中:

  • 如果在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 Cinjected-class-name([类]),或
  • [...此处无关...]

这个名字被认为是命名类C的构造函数。 [ 注意:例如,构造函数在详细类型说明符中不是可接受的查找结果,因此构造函数不会用于代替注入的-类名—— 尾注 ] 这样的构造函数名称只能用于命名构造函数的声明的 declarator-id 或 using 声明中。 [ 示例:

struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba;            // object of type A
A::A a;             // error, A​::​A is not a type name
struct A::A a2;     // object of type A

— 结束示例 ]

typename C::TA::A 是同一种东西,它是查找不忽略函数名的方法(typename 不会导致函数名被忽略)。所以,在typename C::T 中,当CT 时,名称T 被认为是命名构造函数。由于它不是类型名称,我们应该得到替换失败并回退到主模板。

归档86818

【讨论】:

  • "(typename 在这里不符合条件,因为不忽略函数名)"——这里没有错字吗?
  • @Quentin 错字是什么?
  • 我理解的双重否定 - 它说 typename 有资格忽略函数名称。
  • @Quentin 这不是双重否定。
  • 那我就是不明白那句话:)
【解决方案2】:

为了完成 Barry 的回答,typename 仅对编译器说以下名称是模板实例化之前执行的分析的类型。实例化后,执行名称查找,就好像 typename 不存在一样,[temp.res]/4:

通常的限定名查找用于查找限定ID即使存在类型名

所以 Clang 是对的。为了获得一致的编译器行为,您可以使用 elaborated type specifier struct C::T 代替 typename C::T

template <class> using void_t = void;
template <class C, class = void> struct X { enum { v = 0 }; };
template <class C> struct X<C, void_t<struct C::T> > { enum { v = 1 }; };
struct T { };
int main() { return X<T>::v; }

【讨论】:

    猜你喜欢
    • 2021-01-25
    • 2019-06-01
    • 2021-04-29
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2014-01-02
    相关资源
    最近更新 更多