级联

2016-12-07 63 views
1

我试图避免这种解决方案的一个问题:级联

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派生了一个派生类(需要一些外部工具来编写一个头文件)。

那么宏连接不工作(毕竟还不确定),任何想法实现呢?

+0

宏连接仅在宏定义中起作用。 –

+0

看来你正在试图混合预处理宏和模板,它们没有什么共同之处。你想达到什么目的?也许你可以简单地使用[typeid](http://en.cppreference.com/w/cpp/language/typeid)? –

+0

@GillBates不,这是意外 –

回答

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

我完全忘了他们!非常感谢,这是完美:) –

+0

@MathieuVanNevel我又增加了另一个例子。实际上,变量模板(从我的角度来看)更易于阅读和组织,但它不是必需的。你可以通过使用专业化。 – skypjack

+0

我打算使用专业化,然后发布您的答案。所以是模板变量更可读和简单。 –

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() 
{} 
+1

你好C我的老朋友。 –

+0

那么没有其他的方法来连接你现在不用C++的名字,我想。谢谢,我会检查typeid确定。 –

+0

@MartinBonner好像看起来不适合我,CRTP也许会破坏一切。我得到了一个FOO_Derived没有声明。 –