我的C 代码在宏 模板编译上失败,为什么此错误

My c++ code failed on a macro+template compilation, why this error?

本文关键字:失败 为什么 错误 编译 代码 我的      更新时间:2023-10-16

我正在使用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&quot"。第二行也是如此。但是第三行未能编译。我的GCC 4.1.2说:

derive.cpp:22:54:错误:宏" _STATIC_ASSERT"通过了2个参数,但仅需1

derive.cpp:在函数'int main()'中:

derive.cpp:22:错误:在此范围中未声明'_static_assert'

如何解决我的案件?非常感谢。

值得注意的是,在编译的解析阶段之前,C 宏已扩展,这是通过对宏的每个参数进行文本替换为匹配的位置来完成的。my_is_base_of<Base,Derived>::value在这里被宏解释为两个参数,因为它使用逗号运算符:my_is_base_of<Base成为第一个参数,而Derived>::value成为第二个参数。这种行为正是由于宏无法(无法)进行解析的事实,因此无法知道逗号是在模板参数的上下文中使用的。为了解决问题,您需要将语句放在括号中:

_static_assert((my_is_base_of<Base,Derived>::value)); 

毫无问题的编译。