我的c ++代码在宏+模板编译时失败了,为什么会出现这个错误?

时间:2016-12-19 05:48:29

标签: c++ templates gcc compilation macros

我使用的是旧版本的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'未在此范围内声明

如何解决我的情况?非常感谢。

1 个答案:

答案 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)); 

编译没有问题。