【问题标题】:Simple way to reference member variables of base class templates引用基类模板成员变量的简单方法
【发布时间】:2020-09-19 11:58:23
【问题描述】:

没有基类名和作用域解析运算符,有没有办法引用基类模板的成员变量?

template<typename D>
struct B0 {
    int value;
};
struct D0: B0<D0> {
    D0() {
        B0<D0>::value = 1; // OK.
        value = 1;         // OK without `B0<D0>::`.
    }
};

template<typename T>
struct B1 {
    T value;
};
template<typename T>
struct D1: B1<T> {
    D1() {
        B1<T>::value = 1; // OK.
        // value = 1; // Compile error without `B1<T>::`.
                      // Compile error: use of undeclared identifier 'value'
                      // `B1<T>::` is tedious everywhere `value` is referenced.
    }
};

template<typename T, typename D>
struct B2 {
    T value;
};
template<typename T>
struct D2: B2<T, D2<T>> { // CRTP
    D2() {
        B2<T, D2<T>>::value = 1; // OK.
        // value = 1; // Compile error without `B2<T, D2<T>>::`.
                      // Compile error: use of undeclared identifier 'value'
                      // `B2<T, D2<T>>::` is more tedious for CRTP.
    }
};

int main() {
    return 0;
}

是否可以不写B1&lt;T&gt;::B2&lt;T, D2&lt;T&gt;&gt;::,这在任何地方引用value 都很乏味?

【问题讨论】:

    标签: c++ templates base-class name-lookup class-template


    【解决方案1】:

    作为解决方案,您必须使名称 value 依赖,以使其对名称查找可见。除了你展示的那个,你还可以:

    1. 使用using介绍名称,

      template<typename T>
      struct D1: B1<T> {
          using B1<T>::value;   // or move it in method's scope according to your intent
          D1() {
              value = 1;        // OK.
          }
      };
      
    2. 使用this-&gt; 验证。

      template<typename T>
      struct D1: B1<T> {
          D1() {
              this->value = 1;  // OK.
          }
      };
      

    【讨论】:

    • IIRC,当几年前 Visual C++ 的模板处理变得更加符合标准时,我们不得不对我们的代码库进行一些更改。在此之前,VC++ 将接受对 value 的引用,而不接受 this-&gt;。您知道标准中要求以 this-&gt; 为前缀的动机是什么,这显然是多余的?为什么继承成员的查找规则与非模板不同?基类定义就在那里……
    • @Peter-ReinstateMonica 该标准规定不在依赖基类中查找非依赖名称。我认为动机是模板基类可能是专门的;然后直到实例化,编译器才能知道数据成员是否存在于基中。然后我们必须使名称依赖,它只会在实例化时查找,到那时必须探索的确切基础特化将是已知的。
    • 感谢您的快速回复。我知道推测动机通常是徒劳的,但是:添加this-&gt; 对未知基类专业化有何影响?当然,它可能会显示编码人员的意图,实际上是在说“我很确定该成员会在那里”,就像演员表显示意图一样。
    • @Peter-ReinstateMonica 因为添加this-&gt; 明确表明该名称是类的数据成员,这取决于模板参数,所以必须在实例化时查找名称.否则,名称可能是其他东西,如全局变量;即使没有资格,也应该找到它并且可以正常工作。编译器只是在第一次报错,它不会在实例化时再次尝试,它可能太复杂了。
    猜你喜欢
    • 2017-10-18
    • 2018-10-08
    • 2021-07-25
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    相关资源
    最近更新 更多