名称和派生名称 class 之间的串联(作为模板参数)

Concatenation between name and derived name class (as template args)

我正在尝试避免此解决方案出现问题:

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 中派生 class 时才存在(需要一些外部工具来编写 header ).

好吧,宏连接不起作用(毕竟不确定),有实现它的想法吗?

如果你能用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() 
{}

自 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 值分开。
否则,您可以完全专业化并丢弃这些变量。
例如:

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, "!");
}