验证单元测试中的static_assert

时间:2016-02-08 20:43:31

标签: c++ unit-testing c++11 googletest

我想确保static_assert在单元测试中正常工作。也就是说,如果我有一个

class MyClass {static_assert(my_type_trait<T>::value, "error"); };

然后在单元测试中MyClass<TypeWithTrait> myClass;应该'通过'而MyClass<TypeWithoutTrait> myClass;应该'失败'。

是否可以做这样的事情?

2 个答案:

答案 0 :(得分:4)

如果要检查某些内容无法编译,则必须在代码外部进行测试。只需写一个简单的文件,如:

#include "MyClass.h"

int main() { 
    MyClass<%T%> m;
}

编写一个单元测试,用不同的%T%值编译该文件。验证编译是否按预期成功,或者在失败文本中按预期失败并显示static_assert

答案 1 :(得分:-1)

Barry的建议是一种可能性,但如果你想要测试很多东西,你需要创建许多小文件。更重要的是,这些文件由于其他原因而无法编译而无法进行编译,从而错误地判断您的测试通过了。

另一种方法是,不使用static_assert,而是使用某种SFINAE来检测是否有效。对于traits类,这有点棘手,但你可以这样做:

template <class T>
using void_t = void;

template <class T>
struct foo;

template <>
struct foo <double> {};

template <class T, class = void>
struct has_foo_trait : std::false_type {};

template <class T>
struct has_foo_trait<T, void_t<decltype(foo<T>{})>> : std::true_type {};

int main(int, char**) {
  std::cerr << has_foo_trait<int>::value;
  std::cerr << has_foo_trait<double>::value;
  return 0;
}

打印出01。所以现在,不是直接从static_assert获得硬故障,而是可以在编译时计算特征存在的值,然后static_assert得到你期望的值。

请注意,traits类很棘手的原因是因为trait被声明为一般模板,只是没有定义。所以做#&#34;通常&#34;元编程在void_t内直接使用类型的东西不起作用。为了在true的{​​{1}}分支中触发软SFINAE错误,我实际上必须默认构造traits类的实例。如果你写了你的特质课程,那么他们不是默认的可构造的,这不会起作用。但总的来说,你不会这样写。很想知道是否有更好的方法来做到这一点