Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将模板参数传递给CRTP?_C++_Templates_Crtp - Fatal编程技术网

C++ 如何将模板参数传递给CRTP?

C++ 如何将模板参数传递给CRTP?,c++,templates,crtp,C++,Templates,Crtp,在以下代码中: template <typename T> class CRTP { public: }; template <int I, typename T> class CRTPInt { public: }; template <template <typename> class T> class Derived : public T<Derived<T>> { public: }; void main()

在以下代码中:

template <typename T>
class CRTP
{
public:
};

template <int I, typename T>
class CRTPInt
{
public:
};

template <template <typename> class T>
class Derived : public T<Derived<T>>
{
public:
};

void main()
{
Derived<CRTP> foo;
Derived<CRTPInt<2>> foo2;
}
模板
类CRTP
{
公众:
};
模板
类CRTPInt
{
公众:
};
模板
派生类:public T
{
公众:
};
void main()
{
衍生食品;
衍生食品2;
}
如何编写CRPTInt,以便传入模板化参数,然后在派生定义中继续

谢谢


Jim

CRTP模式通常用于启用静态多态性混合(参数化)行为的能力。为了说明两个备选方案,可以方便地首先定义一个通用模板

template
<
        typename Derived
>
class enable_down_cast
{
private:
        // typedefs

        typedef enable_down_cast Base;

public:
        Derived const* self() const
        {
                // casting "down" the inheritance hierarchy
                return static_cast<Derived const*>(this);
        }

        // write the non-const version in terms of the const version
        // Effective C++ 3rd ed., Item 3 (p. 24-25)
        Derived* self()
        {
                return const_cast<Derived*>(static_cast<Base const*>(this)->self());
        }

protected:
        // disable deletion of Derived* through Base*
        // enable deletion of Base* through Derived*
        ~enable_down_cast() = default; // C++11 only, use ~enable_down_cast() {} in C++98
};
另一种方法是参数化接口的不同实现。这一次,类模板同时依赖于模板参数和非类型参数

template<template<int> class F, int X>
class BarInterface
:
    public enable_down_cast< F<X> >
{
private:
    // dependent name now in scope
    using enable_down_cast< F<X> >::self;

public:
    // interface
    void bar() { self()->do_bar(); }    

protected:
    // disable deletion of Derived* through Base*
    // enable deletion of Base* through Derived*
    ~BarInterface() = default; // C++11 only, use ~BarInterface() {} in C++98/03
};

更新:根据来自的讨论,我发现原始答案仅在Visual Studio 2010上编译,而不是在gcc上编译,因为某些特定于Microsoft的、不可移植的功能。例如,
enable\u down\u cast
中的
self()
函数在其派生类中是(模板)依赖的名称,因此,如果没有使用指令显式执行
,该函数将不可见。此外,我还添加了具有正确保护级别的默认析构函数。最后,我将我的原始类
enable_crtp
重命名为
enable_down_cast
,因为它正是这样做的:手动启用静态多形性,就像编译器自动启用动态多态性一样。

我希望避免派生的2解决方案。我正在组装一个模块化的摄像头对象,该对象允许策略混合和匹配镜头、小车等。我希望能够将变焦镜头指定为焦距最小值和焦距最大值,即摄像头,但作为回报,镜头需要访问摄像头以调用其他模块的功能。(事实上,在镜头的情况下不是这样,但在娃娃和头上是这样。)@Tavison对于基于策略的设计,您并不总是需要CRTP。例如,您可以直接从每个策略派生:
template类摄影机:public ZoomPolicy,public DolliesPlicy{}
相反,您可以让每个
ConcreteZoomPolicy
从一个特定的
ZoomInterface
等派生出来。@Tavison要继续,您可以使
模板类ZoomInterface:private enable\u crpt{}模板类ZoomImpl:publiczoominterface{}的实现。然后你可以有一个
摄像机
我会处理这个问题,当它工作时接受你的回答。我知道我需要另一个图层,但找不到。这不是在VC10中编译的。我得到这些错误。错误C2923:'F':'X'不是参数“”的有效模板类型参数请参见'X'的声明请参见对正在编译的类模板实例化'BarInterface'的引用错误C3201:类模板'BarImpl'的模板参数列表与模板参数'F'的模板参数列表不匹配请参见对类模板的引用正在编译实例化“BarImpl”
class FooImpl
:
    public FooInterface< FooImpl > 
{
private:
    // implementation
    friend class FooInterface< FooImpl > ;
    void do_foo() { std::cout << "Foo\n"; }
};

class AnotherFooImpl
:
    public FooInterface< AnotherFooImpl > 
{
private:
    // implementation
    friend class FooInterface< AnotherFooImpl >;
    void do_foo() { std::cout << "AnotherFoo\n"; }
};
template<template<int> class F, int X>
class BarInterface
:
    public enable_down_cast< F<X> >
{
private:
    // dependent name now in scope
    using enable_down_cast< F<X> >::self;

public:
    // interface
    void bar() { self()->do_bar(); }    

protected:
    // disable deletion of Derived* through Base*
    // enable deletion of Base* through Derived*
    ~BarInterface() = default; // C++11 only, use ~BarInterface() {} in C++98/03
};
template< int X >
class BarImpl
:
    public BarInterface< BarImpl, X > 
{
private:
    // implementation
    friend class BarInterface< ::BarImpl, X >;
    void do_bar() { std::cout << X << "\n"; }    
};
int main()
{
    FooImpl f1;         
    AnotherFooImpl f2;
    BarImpl< 1 > b1;
    BarImpl< 2 > b2;

    f1.foo();
    f2.foo();
    b1.bar();
    b2.bar();

    return 0;
}
class Derived1
: 
   public CRTP< Derived1 > 
{

};

template<int I>
class Derived2
: 
   public CRTPInt< Derived2, I >
{

};