概念lite会改变CRTP实现静态多态的需求吗?

时间:2013-11-10 03:44:50

标签: c++ metaprogramming crtp c++-concepts

自从几年前我发现CRTP以来,我在许多地方使用它来实现非常密集的面向计算的代码的编译时多态性。当人们在运行时关注通用性和最大性能时,以通用方式将成员函数“注入”到类中是很棒的。

我已经阅读/观看了concepts lite上的几件事情,这将是(我希望)下一个C++标准的一部分。以更抽象和通用的方式设计函数绝对是绝对美妙的,避免了我目前使用的SFINAE/std::enable_if的可疑行。

我没有测试实现概念的g++分支,以及以新的方式研究我喜欢的元编程方法。但也许有些人有。我的第一个想法是概念不会解决静态多态的问题,但由于这些事情可能严重依赖于技巧,我可能是错的。所以我的问题如下:概念lite能否以更方便的方式实现编译时多态(我们目前可以通过CRTP完成)?(代码示例是欢迎)。

3 个答案:

答案 0 :(得分:6)

我不应该这么认为。 Concepts Lite将取代您对enable_if的使用,但我不确定它是否允许CRTP的新技术。另一方面,可能会有一些有趣的事情可以做。

我会说我遇到了一些早期实现的概念精简版的CRTP问题。检查约束要求类型参数为完整类型。如果您在派生类上参数化了基类,则需要将检查推迟到使用点。例如:

template<Fooable D>
struct crtp {
  void f() {
    static_cast<D*>(this)->g();
  }
};

struct derived : crtp<derived> { // Error!
};

当您尝试检查Fooable<derived>时,尚未定义派生。最好这样写:

template<typename D>
struct crtp {
  void f() requires Fooable<D>() {
    static_cast<D*>(this)->g();
  }
};

现在,仅在调用Fooable<D>()时检查f()

只是一个FYI。

答案 1 :(得分:5)

  

所以我的问题如下:概念lite能否以更方便的方式实现编译时多态(我们目前可以通过CRTP实现)? (欢迎使用代码示例)。

不 - 他们一般不会压制CRTP。 Concepts lite主要是关于重载的简易性和定义泛型函数,以及语法检查的简易性:

template<typename T>
concept bool EqualityComparable()
{
    return requires(T a, T b)
    {
        bool = {a == b};
        bool = {a != b};
    };
}

template<InputIterator I, EqualityComparable T>
I find(I first, I last, T x);
// or
template<InputIterator I>
I find(I first, I last, EqualityComparable x);

我认为概念lite会抑制std::enable_if的许多用例。

CRTP有不同的用例,其中一些确实与重载有关,例如:

template<typename Derived>
void do_something(const CRTP_Base<Derived> &x);

CRTP不仅限于重载,还有其他应用程序:例如std::enable_shared_from_this的主要用例并不意味着任何重载:

class Widget : std::enable_shared_from_this<Widget>
{
    // ...
};

CRTP的一些用例甚至涉及虚函数 - 例如Cloneable接口的自动实现:

// Simple example, no covariance, etc
struct Base
{
    typedef unique_ptr<Base> Unique;

    virtual Unique clone() const = 0;
    virtual ~Base() = default;
};

template<typename Derived>
struct ImplementCloneable: protected Base
{
    Unique clone() const override
    {
        return Unique(new Derived(static_cast<const Derived&>(*this)));
    }
protected:
    ~ImplementCloneable() = default;
};

struct Widget: ImplementCloneable<Widget>
{
};

答案 2 :(得分:0)

据我了解,应该可以使用Concepts Lite来定义一种静态界面&#39;它表示概念要求某些成员函数存在于类中,并且可以使用某些签名进行调用。在某些情况下,这似乎对静态多态有用。

我不认为这确实是Concepts Lite的预期用途。在会谈中我看到的建议似乎是应该有相对较少的概念,它们应该是相当基础的(想象一下前向迭代器的概念)而不是用于定义ad-hoc静态接口。