代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

使用静态断言检查传递给宏的类型

  •  21
  • Matt Joiner  · 技术社区  · 14 年前

    不幸的是,我的库的原始版本中还有几个宏,它们使用了一些非常疯狂的C语言,特别是,我有一系列的宏,它们希望将某些类型传递给它们。 有没有可能做一些类似的事情:

    static_assert(decltype(retval) == bool);
    

    是的,我知道宏是坏的。我知道C++不是C等。

    更新0

    related code ,以及 source file

    4 回复  |  直到 14 年前
        1
  •  54
  •   Błażej Czapp    7 年前

    我发现这是最干净的@ UncleBens

    #include <type_traits>
    
    static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
    
        2
  •  3
  •   MSalters    14 年前

    看来你需要 decltype 因为你有一个表达式,但是想验证一个类型。现在已经有足够的方法来完成这(C++ 03)了。例如,检查bool

    inline void mustBeBool(bool) { }
    template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)
    
    // Use:
    #define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
    
        3
  •  2
  •   Bart van Ingen Schenau    14 年前

    免责声明:这是一个错误的答案,肯定有更好的解决方案。举个例子:)

    它肯定已经实现了,但是实现自己是微不足道的;

    template <class T1, class T2> struct CheckSameType; //no definition
    template <class T> struct CheckSameType<T,T>{}; //
    
    template <class T1, class T2>
    AssertHasType(T2)
    {
       CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
    }
    

    像这样使用:

    AssertHasType<bool>(retval);
    

    template <class T1, class T2> struct SameType
    {
        enum{value = false};
    }
    template <class T> struct SameType<T,T>
    {
        enum{value = true};
    }; 
    

    像这样使用

    static_assert(SameType<decltype(retval), bool>::value);
    
        4
  •  1
  •   Cheers and hth. - Alf    14 年前

    大多数宏可以替换为 inline 函数和/或模板。作为一个例子,过于聪明的参数大小检查Posix isnan 宏是C++中的模板。哦,坏例子,但是你知道了。

    该规则的主要例外是基本上实现更高级别的宏 语言 特征。例如,更智能的异常处理、协方差或参数化的声明集。

    在某些情况下,无法合理表达为 内联 函数或模板,可以替换为一种更智能的预处理,即代码生成。然后在某个地方有一个脚本来生成必要的代码。例如,可以用纯宏和模板在纯C++中执行选项类,但是它有毛茸茸的,并且作为更容易的GROK和可能更可维护的替代性的,可以使用生成必要的类的脚本,以额外的构建步骤和处理多种语言为代价。

    干杯。,