我使用的是旧版本的gcc,所以我尝试实现了几个有用的type_traits元素,比如is_base_of和static_assert,如下所示:
template <typename Base, typename Derived>
struct my_is_base_of{
struct Yes{char _;};
struct No{char _[2];};
static Yes _test(const Base*);
static No _test(void*);
static const bool value=sizeof(_test((Derived*)0))==sizeof(Yes);
};
template<bool b>struct _static_assert_test{static char _;};
template<>struct _static_assert_test<false>{};
#define _static_assert(x) _static_assert_test<x>::_
struct Base{};
struct Derived : Base {};
struct C {};
#include<iostream>
int main()
{
std::cout<<std::boolalpha<<my_is_base_of<Base,Derived>::value<<std::endl;
_static_assert(sizeof(int)==4);
_static_assert(my_is_base_of<Base,Derived>::value);//fails to compile
return 0;
}
嗯,主要功能的第一行编译并打印“true”。第二行也是如此。但是第3行无法编译。我的gcc 4.1.2说:
derive.cpp:22:54:错误:宏“_static_assert”传递了2个参数,但只需1个
derive.cpp:在函数'int main()'中:
derive.cpp:22:错误:'_static_assert'未在此范围内声明
如何解决我的情况?非常感谢。
答案 0 :(得分:3)
值得注意的是,在编译的解析阶段之前扩展了C ++宏,这是通过将宏的每个参数文本替换为匹配的位置来完成的。 my_is_base_of<Base,Derived>::value
在这里被宏解释为两个参数,因为它使用逗号运算符:my_is_base_of<Base
成为第一个参数,Derived>::value
成为第二个参数。这种行为正是由于宏不能(不能)执行解析这样的事实,因此它无法知道在模板参数的上下文中使用逗号。要解决此问题,您需要将语句放在括号中:
_static_assert((my_is_base_of<Base,Derived>::value));
编译没有问题。