标签: crtp

C++:使用CRTP,派生类中定义的类在基类中不可访问

这是(简化的)基类:

template <class T>
class SharedObject
{
protected:
    QExplicitlySharedDataPointer <typename T::Data> d;
};
Run Code Online (Sandbox Code Playgroud)

以下是派生的:

class ThisWontCompile : public SharedObject <ThisWontCompile>
{
private:
    friend class SharedObject;
    struct Data : public QSharedData
    {
        int id;
    };
};
Run Code Online (Sandbox Code Playgroud)

是否有任何解决方法从SharedObject访问ThisWontCompile :: Data?使用基础对象中的派生对象究竟能做什么,究竟什么不能完成?

c++ qt templates crtp

7
推荐指数
1
解决办法
1309
查看次数

使用CRTP时如何获取模板参数的大小?

在VC++ 10中,以下示例因错误C2027而失败:"使用未定义类型'X'".但是g ++ 4.6编译得很好.

template<class T>
class C
{
    static const size_t size = sizeof(T);
};

class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud)

那么哪一个是对的?我将如何做到这一点,以便它适用于主流编译器?

这并不是什么大不了的事,因为VC++仍然允许在C的成员函数中使用sizeof(T).我只需要重复一些烦人的长类型定义.

编辑: 我意识到我的例子很糟糕,因为我真正想做的是将大小用作编译时常量,这样:

template<size_t size> class C2 { };

template<class T>
class C
{
   typedef C2<sizeof(T)> A;
};

class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud)

两个编译器都拒绝这个,所以我认为它可能不可能,但就像我说我仍然可以在函数内部使用sizeof.我只是希望我不必在每个函数中重复typedef.

template<size_t size> class C2 { };

template<class T>
class C
{
    void foo() { typedef C2<sizeof(T)> A; }
};

class X : public C<X> { };
Run Code Online (Sandbox Code Playgroud)

c++ templates crtp

7
推荐指数
1
解决办法
928
查看次数

C++ - 循环依赖(在模板化基类中使用内部类型的子类)

我在模板化的类中遇到了循环依赖的问题.有一个代码示例:

template <typename T> struct A 
{
  typedef typename T::C D;
  //typename T::C c;
};

struct B : public A<B>
{
  struct C {};
};
Run Code Online (Sandbox Code Playgroud)

当我尝试实例化B时,我得到一个编译器错误:'C'不是'B'(MSVC)的成员无效使用不完整类型'struct B'(GCC).
更改样本以使其工作的最佳方法是什么?

c++ templates circular-dependency crtp incomplete-type

7
推荐指数
1
解决办法
233
查看次数

确保派生类实现静态方法

我想确保派生类实现一个特定的静态方法.我认为这样做应该可以使用static_assert,std :: is_same,decltype,CRTP并且可能使用SFINAE.但是,到目前为止,我发现的类似代码非常复杂,似乎我还没有完全理解它使我无法将其用于我的需求.

到目前为止我尝试过的是这个

template <class T>
class Base 
{
    static_assert(std::is_same<decltype(T::foo(1)), int>::value, "ERROR STRING");
};

class Derived : public Base <Derived>
{
public:
    static int foo(int i) { return 42; };
};
Run Code Online (Sandbox Code Playgroud)

但是,它没有编译告诉我,即使方法正确实现,Derived也没有名为foo的元素.此外,在static_assert内的表达式中为foo提供实际参数会感觉不对.

搜索SO揭示了一个类似的问题,最终引导我到这段代码,检查一个类型有方法begin()和end()返回迭代器.所以我试着采用这个代码来满足我的需求.

template <class T>
class Base 
{
    template<typename C>
    static char(&g(typename std::enable_if<std::is_same<decltype(static_cast<int(C::*)(int)>(&C::foo)), int(C::*)(int)>::value, void>::type*))[1];

    template<typename C>
    static char(&g(...))[2];

    static_assert(sizeof(g<T>(0)) == 1, "ERROR STRING");
};
Run Code Online (Sandbox Code Playgroud)

但是这段代码没有编译,因为断言触发了.

所以我的问题是

  1. 为什么编译器在我的第一个例子中找不到Derived :: foo?
  2. typename C::const_iterator(C::*)() const示例代码到底意味着什么?是不是一个const函数返回C …

c++ static-assert crtp type-traits c++11

7
推荐指数
1
解决办法
774
查看次数

如何在C++中强制使用奇怪的重复模板模式

我有以下基本模板类.

template<typename T>
class Base {
  public:
    void do_something() {
    }
};
Run Code Online (Sandbox Code Playgroud)

它旨在用作奇怪的重复模板模式.它应该是继承的class B : public Base<B>.它不能像继承一样继承class B : public Base<SomeoneElse>.我想静态地执行这个要求.如果有人使用了这个错误,我预计编译阶段会出错.

我正在做的是把一个static_cast<T const&>(*this)do_something().这样,继承模板的类是继承自作为模板参数提供的类.抱歉这个令人困惑的表情.用简单的英语,它需要B是或继承SomeoneElseclass B : public Base<SomeoneElse>.

我不知道这是否是实现这一目标的最佳方式.看起来很粗鲁.

但是我想做更多.我想确保BSomeoneElse本身.我怎样才能做到这一点?

c++ inheritance templates crtp

7
推荐指数
2
解决办法
586
查看次数

为类型列表创建别名并将其作为模板参数传递

我使用可变参数模板来实现访问者模式:

template<typename... Types>
class Visitor;

template<typename Type>
class Visitor<Type> {
    public:
        virtual void visit(Type &visitable) = 0;
};

template<typename Type, typename... Types>
class Visitor<Type, Types...>: public Visitor<Types...> {
    public:
        using Visitor<Types...>::visit;

        virtual void visit(Type &visitable) = 0;
};


template<typename... Types>
class VisitableInterface {
    public:
        virtual void accept(Visitor<Types...> &visitor) = 0;
};

template<typename Derived, typename... Types>
class Visitable : public VisitableInterface<Types...> {
    public:
        virtual void accept(Visitor<Types...> &visitor) {
            visitor.visit(static_cast<Derived&>(*this));
        }
};

class IntegerElement;
class StringElement;
class BoxElement;
class ImageElement;

class IntegerElement: …
Run Code Online (Sandbox Code Playgroud)

c++ crtp variadic-templates c++11 c++14

7
推荐指数
1
解决办法
418
查看次数

是否可以使用CRTP访问父类体内的成员?

在使用CRTP时,C++ 11/14/17中是否有一种方法可以访问父类中的子类成员?

template <typename T>
class A {
public:
    using C = typename std::result_of<decltype(&T::next)(T)>::type;
};

class B : A<B> {
public:
    int next() { ... };
};
Run Code Online (Sandbox Code Playgroud)

这应该导致A<B>::CB::C存在int.

c++ templates crtp

7
推荐指数
1
解决办法
139
查看次数

CRTP:为什么获取嵌套类型和派生类的嵌套方法之间存在差异?

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()
{

}
Run Code Online (Sandbox Code Playgroud)

crtp_type导致编译错误,虽然crtp_method编译都很好,但两者都试图访问Derived类中定义的内容.什么是解释这种差异的C++规范?

c++ templates crtp

7
推荐指数
1
解决办法
180
查看次数

CRTP和模板模板参数限制

我正在尝试使用CRTP,但我很困惑为什么以下代码无法编译.

template<template<class...> class CBase>
struct ComponentX : public CBase<ComponentX>
  {
  // This does NOT compile
  };

template<template<class...> class CBase>
struct ComponentY : public CBase<int>
  {
  // This does compile
  };
Run Code Online (Sandbox Code Playgroud)

您知道在CRTP的情况下模板模板参数是否有一些限制?

c++ templates crtp template-meta-programming

7
推荐指数
1
解决办法
122
查看次数

惰性评估依赖类型(CRTP)

我希望以下代码能够工作:

template <typename Self>
struct foo_base {
    auto get(typename Self::type n) { return n; }
};

template <typename T>
struct foo : public foo_base<foo<T>> {
    using type = T;
};
Run Code Online (Sandbox Code Playgroud)

问题当然是首先实例化基础,因此您不能引用派生成员类型.我需要在这里进行某种懒惰的评估.

我已经尝试制作功能模板并在其上安装了SFINAE,类似于:

template <typename Self>
struct foo_base {
    template <typename T, typename = std::enable_if_t<std::is_same_v<T, typename Self::type>>>
    auto get(T n) { return n; }
};
Run Code Online (Sandbox Code Playgroud)

但它似乎不会影响订单.有任何想法吗?

编辑:

解决方案的限制:

  • 我无法从派生类传递类型作为模板参数.主要原因是:构造类型很复杂,有几百个字符.所以不能做类似的事情struct foo : foo_base<foo<T>, T>或变种.
  • 我需要将函数约束到该类型,我无法检查函数内部.也许派生类中存在重载.

c++ crtp c++17

7
推荐指数
1
解决办法
291
查看次数