如何用宏做static_assert?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用宏做static_assert?相关的知识,希望对你有一定的参考价值。

我曾尝试使用this suggestion来执行静态断言,但如果我在模板的方法中使用它,则不会出现编译错误。

示例如下:

#include <iostream>

#define STATIC_ASSERT(expr, msg)               
{                                              
    char STATIC_ASSERTION__##msg[(expr)?1:-1]; 
    (void)STATIC_ASSERTION__##msg[0];          
}

template <typename T >
class A
{
public:
  int foo(const int k )
  {
    // does not work
    STATIC_ASSERT( k > 9, error_msg );
    return k+5;
  }
};

int bar(const int k )
{
  // works fine
  //STATIC_ASSERT( k > 9, error_msg );
  return k+5;
}

int main()
{
  A<int> a;
  const int v = 2;

  std::cout<<a.foo(v)<<std::endl;
  std::cout<<bar(v)<<std::endl;

  // works fine
  //STATIC_ASSERT( v > 9, error_msg );
}

我用g ++ 4.7.2编译它,并警告说c ++ ISO不支持VLA:

g++ -Wall -g  -std=c++98 -Wextra -pedantic gvh.cpp

那么,为什么在模板方法中使用STATIC_ASSERT时编译不会失败?有没有办法让它失败?

注意:我需要一个c ++ 98(甚至可能是c ++ 03)解决方案,如果可能的话只需要宏。

答案

在C ++ 11之前,我通常会这样做:

typedef int static_assert_something[something ? 1 : -1];

你也可以看看boost static assert。但它对我来说太过臃肿了。很容易让事情变得更大,很难让它们变得更好。

另一答案

考虑像Boost.StaticAssert这样的东西,虽然如果您无法使用它,您可以尝试定义模板。

template<bool>
struct static_assertion;

template<>
struct static_assertion<true> {};

虽然这样做的缺点是没有与之相关的消息。

在对StackOverflow进行了一些搜索之后,我偶然发现了this question,它有一个类似于我的答案,以及一些没有提升的替代方案。

另一答案

这基本上是Maxim的答案,更方便的界面。我从here拿走了它。关于它的好处是使用模板可以防止用户传递非编译时常量值作为条件。

template<bool Is_Condition_Met>
struct Static_assert_cpp98
{
  static void apply() {static const char junk[ Is_Condition_Met ? 1 : -1 ];}
};

template<>
struct Static_assert_cpp98<true>
{
  static void apply() {}
};

#define STATIC_ASSERT_CPP98(condition) Static_assert_cpp98<condition>::apply()
另一答案

如果添加对相关方法的调用(a.foo();),则静态断言将失败(之后将编译该方法)。你知道你不应该在运行时值上静态断言,比如我认为的“k”。

另一答案
int foo(const int k)
{
  STATIC_ASSERT( k > 9, error_msg );
  return k+5;
}

静态断言仅适用于编译时常量表达式。

k不是编译时常量表达式。

非模板参数是模板实例化期间的编译时常量表达式,因此您可以调整代码:

template <int K>
int foo()
{
  STATIC_ASSERT( K > 9, error_msg );
  return K+5;
}

以上是关于如何用宏做static_assert?的主要内容,如果未能解决你的问题,请参考以下文章

Android NavController:如何用相同的动作打开相同的片段

如何用 Android 数据绑定替换 androidx.fragment.app.FragmentContainerView 中的片段

如何用ffmpeg截取视频片段&截取时间不准确的坑

static_assert 中的 std::pow 触发错误 C2057?

如何用opengl制作低分辨率图形? [关闭]

如何用CSS使图片自适应显示宽度