我有一个模板类,我想要做的是以下
(1)在某种意义上是自动处理的,如果传递的模板参数不支持该类使用的某些功能,则代码将无法编译。但是这个错误可能会很晚才被发现。我希望检查尽可能早。我还想要实现的是,传递的模板参数必须从我提供的基类型派生出来,这应该是显而易见的。
首先,这是误入歧途吗?如果不是我该怎么做? (最简单的方法,C ++对我来说还是新手)
感谢stackoverflow,你真的加快了我的C ++学习速度。
答案 0 :(得分:42)
鉴于某些完整类型MyBase
,如果T
不是来自MyBase
,则以下内容会产生编译时错误:
#include <boost/type_traits/is_base_of.hpp>
#include <boost/static_assert.hpp>
template<typename T>
class Foo {
BOOST_STATIC_ASSERT_MSG(
(boost::is_base_of<MyBase, T>::value),
"T must be a descendant of MyBase"
);
// Foo implementation as normal
};
如果您正在使用带有TR1的C ++ 03编译器,则可以使用std::tr1::is_base_of
代替boost::is_base_of
;如果您使用的是C ++ 11编译器,则可以使用std::is_base_of
代替boost::is_base_of
和static_assert
关键字而不是BOOST_STATIC_ASSERT_MSG
宏:
#include <type_traits>
template<typename T>
class Foo {
static_assert(
std::is_base_of<MyBase, T>::value,
"T must be a descendant of MyBase"
);
// Foo implementation as normal
};
N.b。对于私有和模糊派生类型,这将产生 true_type
,因此,如果您真正需要的是将T
视为-a ,则这是不够的MyBase
(在大多数情况下)。
文档链接:
Boost。StaticAssert
Boost。TypeTraits
答案 1 :(得分:4)
从“现代C ++设计”,第2.7章(“在编译时检测可转换性和继承”):您可以使用sizeof
技巧:
typedef char Small;
class Big { char dummy[2]; };
Small Test(Base1);
Big Test(...);
const bool isSubclassOfBase1 = sizeof(Test(Derived1())) == sizeof(Small);
它利用了sizeof(...)
可以找出表达式求值的类型的事实,并且由于返回值具有不同的大小,==
检查的计算结果为true或false。如果Derived1确实是Base1的基础,则选择Small Test(Base1);
重载并且isSubclassOfBase1
为真。
从此扩展,您可以封装检查并执行静态断言以使其在编译时失败:
#include <boost/static_assert.hpp>
class A {};
class B: public A {};
class C {};
template<class Base, class Derived>
struct SubclassCheck
{
typedef char Yes;
class No { char dummy[2]; };
static Yes Test(Base);
static No Test(...);
enum {
Value = (sizeof(Test(*(Derived*)NULL)) == sizeof(Yes))
};
};
#define CHECK_DERIVES(b,d)\
BOOST_STATIC_ASSERT((SubclassCheck<b,d>::Value));
int
main()
{
CHECK_DERIVES(A, B);
// CHECK_DERIVES(A, C); // fails
}
您可以使用任何其他静态断言实现,不一定是Boost的。
答案 2 :(得分:0)
是的,这是自动处理的,因为如果参数不支持你用它做的事情,将导致编译错误。手动检查类型是否是另一种类型的子类型只能在运行时完成(AFAIK),这比远晚于编译时间。我不知道你迟到检测到的错误是什么意思,编译时间早就得到了。此外,如果每个人都检查了他们的模板参数的类型,那么STL不能使用指针以及基于类的实际迭代器,并且不会那么灵活。
至于让您的用户了解要求,只需在文档中提供。