标签: crtp

什么是奇怪的重复模板模式(CRTP)?

没有参考书,任何人都可以CRTP用代码示例提供一个很好的解释吗?

c++ templates c++-faq crtp

173
推荐指数
5
解决办法
4万
查看次数

Java Enum定义

我以为我很了解Java泛型,但后来我在java.lang.Enum中遇到了以下内容:

class Enum<E extends Enum<E>>
Run Code Online (Sandbox Code Playgroud)

有人可以解释如何解释这个类型参数?用于提供可以使用类似类型参数的其他示例的加分点.

java generics enums crtp

146
推荐指数
3
解决办法
2万
查看次数

CRTP避免动态多态

如何在C++中使用CRTP来避免虚拟成员函数的开销?

c++ virtual templates crtp

88
推荐指数
3
解决办法
3万
查看次数

C++静态多态(CRTP)并使用派生类中的typedef

我阅读了维基百科关于C++中用于执行静态(读取:编译时)多态的奇怪重复模板模式的文章.我想概括它,以便我可以根据派生类型更改函数的返回类型.(这似乎应该是可能的,因为基类型知道模板参数中的派生类型).不幸的是,以下代码将无法使用MSVC 2010进行编译(我现在没有轻松访问gcc所以我还没有尝试过).谁知道为什么?

template <typename derived_t>
class base {
public:
    typedef typename derived_t::value_type value_type;
    value_type foo() {
        return static_cast<derived_t*>(this)->foo();
    }
};

template <typename T>
class derived : public base<derived<T> > {
public:
    typedef T value_type;
    value_type foo() {
        return T(); //return some T object (assumes T is default constructable)
    }
};

int main() {
    derived<int> a;
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,我有一个使用额外模板参数的解决方法,但我不喜欢它 - 当在继承链上传递许多类型时会变得非常冗长.

template <typename derived_t, typename value_type>
class base { ... };

template <typename T>
class derived : public …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance templates typedef crtp

62
推荐指数
3
解决办法
1万
查看次数

无效使用不完整类型

我正在尝试在项目中使用子类的typedef,我在下面的示例中已经分离了我的问题.

有谁知道我哪里出错了?

template<typename Subclass>
class A {
    public:
        //Why doesn't it like this?
        void action(typename Subclass::mytype var) {
            (static_cast<Subclass*>(this))->do_action(var);
        }
};

class B : public A<B> {
    public:
        typedef int mytype;

        B() {}

        void do_action(mytype var) {
            // Do stuff
        }
};

int main(int argc, char** argv) {
    B myInstance;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出:

sean@SEAN-PC:~/Documents/LucadeStudios/experiments$ g++ -o test test.cpp
test.cpp: In instantiation of ‘A<B>’:
test.cpp:10:   instantiated from here
test.cpp:5: error: invalid use of incomplete type ‘class B’
test.cpp:10: error: forward …
Run Code Online (Sandbox Code Playgroud)

c++ templates typedef crtp

53
推荐指数
2
解决办法
10万
查看次数

"奇怪的重复模板模式"的实际应用

" 奇怪的重复模板模式 "有哪些实际用途?通常显示的" 计数类 "示例对我来说并不是一个令人信服的例子.

c++ templates design-patterns crtp f-bounded-polymorphism

42
推荐指数
2
解决办法
1万
查看次数

为什么自动返回类型推导与未完全定义的类型一起工作?

考虑以下:

template<typename Der>
struct Base {
    // NOTE: if I replace the decltype(...) below with auto, code compiles
    decltype(&Der::operator()) getCallOperator() const {
        return &Der::operator();
    }
};

struct Foo : Base<Foo> {
    double operator()(int, int) const {
        return 0.0;
    }
};

int main() {
    Foo f;
    auto callOp = f.getCallOperator();
}
Run Code Online (Sandbox Code Playgroud)

我想在CRTP基类中创建一个成员函数,其返回类型取决于operator()派生类中的签名.但decltype(&Der::operator())无法编译; 将operator()在成员函数Foo是不可见的.我假设这是因为基类模板在Foo完全定义之前被实例化.

令人惊讶的是,如果我auto为返回类型放置它编译.我假设这auto会使编译器从函数体中推导出返回类型并失败 - 因为正文使用了未完全定义的Foo类型.

MSVC 2015.3和Clang 3.8的行为相同

为什么代码开始使用auto?难道auto类型推演莫名其妙"延迟"的实例?或者使用与手写返回类型表达式不同的上下文?

c++ crtp return-type-deduction c++14

39
推荐指数
1
解决办法
1010
查看次数

operator =和在C++中没有继承的函数?

在我刚刚进行的测试之前,我相信只有构造函数不会在C++中继承.但显然,任务operator=不是......

  1. 这是什么原因?
  2. 是否有任何解决方法来继承赋值运算符?
  3. 是不是也为的情况下operator+=,operator-=...?
  4. 是否继承了所有其他函数(除了构造函数/运算符=)?

事实上,我在做一些CRTP时遇到了这个问题:

template<class Crtp> class Base
{
    inline Crtp& operator=(const Base<Crtp>& rhs) {/*SOMETHING*/; return static_cast<Crtp&>(*this);}
};

class Derived1 : public Base<Derived1>
{
};

class Derived2 : public Base<Derived2>
{
};
Run Code Online (Sandbox Code Playgroud)

是否有任何解决方案可以使其工作?

编辑:好的,我已经解决了这个问题.为什么以下不起作用?如何解决问题?

#include <iostream>
#include <type_traits>

// Base class
template<template<typename, unsigned int> class CRTP, typename T, unsigned int N> class Base
{
    // Cast to base
    public:
        inline Base<CRTP, T, N>& operator()()
        {
            return *this;
        }

    // Operator =
    public: …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance operator-overloading crtp

36
推荐指数
3
解决办法
2万
查看次数

带有受保护派生成员的CRTP

CRTP模式中,如果我们想要将派生类中的实现函数保持为受保护,则会遇到问题.我们必须将基类声明为派生类的朋友或使用类似的东西(我没有尝试过链接文章的方法).是否有其他(简单)方法允许将派生类中的实现函数保持为受保护?

编辑:这是一个简单的代码示例:

template<class D> 
class C {
public:
    void base_foo()
    {
        static_cast<D*>(this)->foo();
    }
};


class D:  public C<D> {
protected: //ERROR!
    void foo() {
    }   
};

int main() {
    D d;
    d.base_foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码给出error: ‘void D::foo()’ is protected了g ++ 4.5.1,但是如果protected被替换为compiles public.

c++ crtp

24
推荐指数
2
解决办法
3728
查看次数

防止用户从错误的CRTP基础派生

我无法想出一个适当的问题标题来描述问题.希望下面的细节清楚地解释了我的问题.

请考虑以下代码

#include <iostream>

template <typename Derived>
class Base
{
    public :

    void call ()
    {
        static_cast<Derived *>(this)->call_impl();
    }
};

class D1 : public Base<D1>
{
    public :

    void call_impl ()
    {
        data_ = 100;
        std::cout << data_ << std::endl;
    }

    private :

    int data_;
};

class D2 : public Base<D1> // This is wrong by intension
{
    public :

    void call_impl ()
    {
        std::cout << data_ << std::endl;
    }

    private :

    int data_;
};

int main ()
{
    D2 …
Run Code Online (Sandbox Code Playgroud)

c++ crtp

24
推荐指数
2
解决办法
2159
查看次数