名称和派生名称类之间的连接(作为模板args)

时间:2016-12-07 08:58:15

标签: c++ templates concatenation crtp

我试图避免此解决方案的问题:

static const int  FOO_Test = 7;

template < typename Derived >
class Foo {

  public:
    static const int  Type;
};

const int  Foo::Type = FOO_##Derived ;

class Test : public Foo<Test> {};

如您所见,我试图获取FOO_Test值,该值仅在有人从Foo创建派生类时才存在(需要一些外部工具来编写标题)。

宏连接是不起作用的(毕竟还不确定),有什么想法可以实现吗?

2 个答案:

答案 0 :(得分:2)

从C ++ 14开始,你可以使用变量模板来做到这一点 它遵循一个最小的工作示例:

class Test;

template<typename> static constexpr int FOO;
template<> constexpr int FOO<Test> = 7;

template <typename Derived>
struct Foo {
    static const int Type;
};

template<typename Derived>
const int Foo<Derived>::Type = FOO<Derived> ;

class Test : public Foo<Test> {};

int main () {
    static_assert(Test::Type == 7, "!");
}

有助于将FOO值与Foo类区分开来 否则,您可以使用完全专业化并丢弃这些变量 举个例子:

class Test;

template <typename Derived>
struct Foo {
    static const int Type;
};

template<>
const int Foo<Test>::Type = 7 ;

class Test : public Foo<Test> {};

int main () {
    static_assert(Test::Type == 7, "!");
}

答案 1 :(得分:0)

如果你可以使用C ++ 14,请使用skypjack的方法。如果你不能,你可以写一些类似的东西:

#define DEFINE_FOO_TYPE(Derived) \
    const int Foo<Derived>::Type = FOO_##Derived

DEFINE_FOO_TYPE(Test);

但如果可能,我会尽量避免使用它。

一个完整的例子:

// This probably wants to go in Foo.h
template < typename Derived >
class Foo {

  public:
    static const int  Type;
};
#define DEFINE_FOO_TYPE(Derived) \
    template <> const int Foo<Derived>::Type = FOO_##Derived

// This probably wants to go in Test.h
static const int  FOO_Test = 7;
class Test : public Foo<Test> {};

// This needs to go in Test.cpp (or some other central place)
// Note that it must follow definition of Test.
DEFINE_FOO_TYPE(Test);

// an empty main so the whole example will compile and run.
int main() 
{}