通过基类实现C++模板特化
我希望能够在我调用foo的构造函数时使编译器大声呼叫,而类 不是从_base *派生的。目前的代码只允许foo < _base *>本身。任何 简单的解决方案?通过基类实现C++模板特化
class _base
{
public:
// ...
};
class _derived: public _base
{
public:
// ...
};
template <typename T>
class foo
{
public:
foo() { void TEMPLATE_ERROR; }
};
template <> foo<_base*>::foo()
{
// this is the only constructor
}
主代码:
foo<_base*> a; // should work
foo<_derived*> b; // should work (but doesnt)
foo<int*> c; // should not work (and infact doesnt)
没有加速,你可以使用类似以下,以确定是否一个指针到类型可以隐式转换为另一个指针到类型:
template <class Derived, class Base>
struct IsConvertible
{
template <class T>
static char test(T*);
template <class T>
static double test(...);
static const bool value = sizeof(test<Base>(static_cast<Derived*>(0))) == 1;
};
要使它在触发编译期错误时间,现在可以在表达式中使用value
,该表达式如果为false,则会导致错误,例如typedef负大小的数组。
template <typename T>
class foo
{
public:
foo()
{
typedef T assert_at_compile_time[IsConvertible<T, _base>::value ? 1 : -1];
}
};
使用SFINAE(通过enable_if
)和Boost的is_convertible
type trait:
template <typename T, typename Enabled = void>
class foo
{
private:
foo(); // Constructor declared private and not implemented.
};
template <typename T>
class foo<T, typename enable_if<is_convertible<T, _base*> >::type>
{
public:
foo() { /* regular code */ }
};
(本机上安装未经测试,还没有得到升压)
Thanx,我读通过链接,他们引发了一些想法。应该是一个很好的解决方案,但我目前还没有使用boost。 – 2009-11-01 18:33:37
Boost的美妙之处在于您只能使用它的一部分 - 特别是大多数头文件可以复制粘贴到项目目录或系统包含目录中。 – 2009-11-01 21:10:21
我知道你没有在你的项目中使用boost,但也许你可以复制粘贴它的一些部分。
我发现了一个简单的解决问题的方法使用boost:
template <typename T>
class foo
{
public:
foo() {
BOOST_STATIC_ASSERT((boost::is_convertible<T,_base*>::value));
}
};
它不需要额外的模板参数,也没有必要为模板特殊化。我用boost 1.40进行了测试。
aaah,谢谢。我努力想通过自己潜入助推器,但我偶然发现了很多代码纠缠,所以我不得不撤退。但是,这正是我正在寻找的东西,谢谢。 – 2009-11-02 08:28:25
如果您想要了解更多信息,请参阅Andrei Alexandrescu的“Modern C++ Design:Generic Programming and Design Patterns Applied”一书。 – 2009-11-02 14:59:27
+1这是一个非常好的。并感谢您的书推荐! – 2009-11-03 00:30:00