【问题标题】:CRTP: why a difference between getting a nested type and nested method of the derived class?CRTP:为什么获取派生类的嵌套类型和嵌套方法之间存在差异?
【发布时间】:2018-07-27 08:03:39
【问题描述】:

CRTP模式中的基类可以访问派生类的成员函数,但不能访问派生类中的嵌套类型。

为什么会有这种差异?

为了说明,请考虑以下代码:

template<typename Derived>
struct crtp_base
{
    void crtp_method() { return static_cast<Derived&>(*this).method(); } // compiles

    using crtp_type = typename Derived::type; // doesn't compile
};

struct X : public crtp_base<X>
{
    void method() {}

    using type = int;
};

int main()
{

}

crtp_type 导致编译错误,而 crtp_method 编译正常,尽管两者都尝试访问 Derived 类中定义的内容。解释这种差异的 C++ 规范是什么?

【问题讨论】:

  • 错误是什么?
  • 错误:“X”中没有名为“type”的类型。这是full program
  • 你为什么使用static_cast&lt;&gt;?只需调用this-&gt;method(); 即可编译(gcc 6.3.0,clang 3.8)
  • @AdrianW 你能发一份编译代码sn-p吗?
  • 你在这里:godbolt.org/g/vPn2JX

标签: c++ templates crtp


【解决方案1】:

这里的区别在于方法的实例化仅在您实际使用它时发生,而 crtp_base 的实例化发生在 public crtp_base&lt;X&gt; 类型 X 仍然不完整。解决方法是使用类型特征:

template<typename x_Target>
struct Trait;

template<typename Derived>
struct crtp_base
{
    void crtp_method() { return static_cast<Derived&>(*this).method(); }

    using crtp_type = typename Trait<Derived>::type;
};

struct X;

template<>
struct Trait<X>
{
    using type = int;
};

struct X : public crtp_base<X>
{
    void method() {}

    using type = Trait<X>::type;
};

【讨论】:

    猜你喜欢
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-08
    • 2016-08-03
    • 2011-06-04
    • 2015-05-22
    • 1970-01-01
    相关资源
    最近更新 更多