使用CRTP,派生“使用".在C ++ 20中 [英] Using CRTP derived "using" in C++20

查看:79
本文介绍了使用CRTP,派生“使用".在C ++ 20中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力使自己了解CRTP和C ++ 20.基本上,我想拥有静态继承,可以使用来访问派生类型的 typedef s和:

I am trying to make my head around CRTP and C++20. Basically, I'd like to have static inheritance that can access the derived type's typedefs and using:

template <typename Derived>
class inherit
{
public:

    Derived& underlying()
    {
        return static_cast<Derived&>(*this);
    }

    Derived const& underlying() const
    {
        return static_cast<Derived const&>(*this);
    }
};

template <typename Derived>
class tester : public inherit<Derived>
{
public:
    using value_type = typename Derived::value_type;
};

class real : public tester<real>
{
public:
    using value_type = int;
};


int main()
{
    return 0;
}

如其他中所述,

This, as explained in some other questions on SO is not allowed as of C++14 (answers that I find refer to that standard and to C++11). My understanding is that there is no way in C++17 either (if my compiler is right).

C ++ 20的当前状态是什么?即将推出的标准还有更好的解决方案吗?

What is the current status with C++20? Are there any better solutions with the upcoming standard?

推荐答案

否,在C ++ 20中仍然不允许.而且,只要派生类在完成实例化基类模板之前是不完整的,就毫无疑问将在C ++中不被允许.毫无疑问,这将保持现状,因为您想要的东西将要求编译器在实例化基类模板之前在某种程度上编译派生类,而这种向前看"的程度是不切实际的.并可能导致无限循环或其他混乱的构造,因为派生的类成员声明/定义可以访问可访问的基类声明.

No, it's still not allowed in C++20. And it will undoubtedly remain not being allowed in C++ so long as the derived class is incomplete until the base class template is finished being instantiated. Which will undoubtedly remain the way things are because what you want would require the compiler to compile the derived class to some degree before instantiating the base class template, and that degree of "look ahead" is just not practical. And can lead to infinite loops or other confused constructs, since derived class member declarations/definitions are expected to be able to access accessible base class declarations.

考虑一些迭代器要求的简单情况.迭代器必须具有 value_type (暂时忽略整个" iterator_traits "业务;我们的目的是使用默认特征),派生类将提供该特性.我们的辅助迭代器CRTP基类将有用地使用派生类 value_type 声明来生成 pointer reference 等.但是派生类的 operator * 必须能够返回 reference ,该引用是从基类继承的,基类本身依赖于编译 value_type 在派生类中的声明.那么...首先编译的是:基类模板实例化还是派生类?它必须是另一个.不能两者都在同一时间.

Consider the simple case of some iterator requirements. Iterators have to have a value_type (ignore the whole "iterator_traits" business for the moment; our intent is to use the default traits), which the derived class will provide. Our helper iterator CRTP base class will helpfully use the derived class value_type declaration to generate pointer, reference, and so forth. But the derived class's operator* needs to be able to return reference, which is inherited from the base class, which itself is dependent on compiling the value_type declaration in the derived class. So... which gets compiled first: the base class template instantiation or the derived class? It has to be one or the other; it can't be both at the same time.

最终的问题是CRTP并不是我们真正想要的.我们真正想要的是能够在中央位置存储一系列声明/定义,然后根据需要将它们注入到类中.IE:一个实际的mixin.使用命名派生类的模板类型的继承仅仅是C ++语言必须实现的最接近的工具.但是,由于继承和模板实例化从未打算满足此需求,因此自然会有与之相关的疣.

The ultimate problem is that the CRTP is just not what we really want. What we really want is to be able to store a sequence of declarations/definitions in a centralized location, then inject them into a class as needed. IE: an actual mixin. Using inheritance of a template type that names the derived class is merely the closest tool the C++ language has to achieve that. But since inheritance and template instantiation were never intended to serve this need, there will naturally be warts associated with it.

因此,您将继续不得不依靠典型的替代方法:使用以派生类类型为模板的特征"类.

So you will continue to have to rely on the typical alternative: using a "traits" class templated on the derived class type.

这篇关于使用CRTP,派生“使用".在C ++ 20中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆