0

我试图使用这个建议来做一个静态断言,但如果我在模板的方法中使用它,我不会收到编译错误。

示例如下:

#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)解决方案,如果可能的话,只能使用宏。

4

5 回答 5

14

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

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

您还可以查看boost static assert。但它太臃肿了,我不喜欢。把事情做大很容易,把事情做得更好很难。

于 2013-01-31T09:09:07.137 回答
3

考虑类似Boost.StaticAssert的东西,但如果您无法使用它,您可以尝试定义模板。

template<bool>
struct static_assertion;

template<>
struct static_assertion<true> {};

尽管这具有没有与之关联的消息的缺点。

在通过 StackOverflow 进行了一些搜索之后,我偶然发现了这个问题,它与我的答案相似,并且有很多替代方案可以在没有提升的情况下进行。

于 2013-01-31T09:14:07.940 回答
3

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

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()
于 2018-03-04T19:11:40.867 回答
1

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

于 2013-01-31T15:57:41.767 回答
1
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;
}
于 2014-03-20T17:20:17.920 回答