ASSERT_DOES_NOT_COMPILE是否可以使用GTest
Is it possible to ASSERT_DOES_NOT_COMPILE with GTest?
假设有一个模板类,在编译时声明整型模板实参必须大于零:
template<int N>
class A
{
public:
A() {
static_assert(N > 0, "N needs to be greater 0.");
}
};
是否有可能创建一个googletest单元测试来编译,但是在运行时报告错误?例如:TEST(TestA, ConstructionNotAllowedWithZero)
{
ASSERT_DOES_NOT_COMPILE(
{
A< 0 > a;
}
);
}
有一种方法,但遗憾的是它可能不是你想要的。
我的第一个想法是试图让SFINAE通过在未求值的上下文中展开无效的lambda来消除过载。不幸的是(在你的情况下),这是特别不允许的…
#define CODE {
utter garbage
}
struct test
{
template<class T>
static std::false_type try_compile(...) { return{}; }
template<class T>
static auto try_compile(int)
-> decltype([]() CODE, void(), std::true_type());
{ return {}; }
};
struct tag {};
using does_compile = decltype(test::try_compile<tag>(0));
输出:./maybe_compile.cpp:88:17: error: lambda expression in an unevaluated operand
-> decltype([]() CODE, void(), std::true_type());
所以它回到了绘图板和一个很好的老系统调用来调用编译器…
#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
#include <sstream>
struct temp_file {
temp_file()
: filename(std::tmpnam(nullptr))
{}
~temp_file() {
std::remove(filename.c_str());
}
std::string filename;
};
bool compiles(const std::string code, std::ostream& reasons)
{
using namespace std::string_literals;
temp_file capture_file;
temp_file cpp_file;
std::ofstream of(cpp_file.filename);
std::copy(std::begin(code), std::end(code), std::ostream_iterator<char>(of));
of.flush();
of.close();
const auto cmd_line = "c++ -x c++ -o /dev/null "s + cpp_file.filename + " 2> " + capture_file.filename;
auto val = system(cmd_line.c_str());
std::ifstream ifs(capture_file.filename);
reasons << ifs.rdbuf();
ifs.close();
return val == 0;
}
auto main() -> int
{
std::stringstream reasons1;
const auto code1 =
R"code(
#include <iostream>
int main() {
return 0;
}
)code";
std::cout << "compiles: " << compiles(code1, reasons1) << std::endl;
std::stringstream reasons2;
const auto code2 =
R"code(
#include <iostream>
int main() {
FOO!!!!XC@£$%^&*()VBNMYGHH
return 0;
}
)code";
std::cout << "compiles: " << compiles(code2, reasons2) << std::endl;
std::cout << "nAnd here's why...n";
std::cout << reasons2.str() << std::endl;
return 0;
}
在我的例子中给出如下示例输出:
compiles: 1
compiles: 0
And here's why...
/var/tmp/tmp.3.2dADZ7:4:9: error: use of undeclared identifier 'FOO'
FOO!!!!XC@£$%^&*()VBNMYGHH
^
/var/tmp/tmp.3.2dADZ7:4:19: error: non-ASCII characters are not allowed outside of literals and identifiers
FOO!!!!XC@£$%^&*()VBNMYGHH
^
2 errors generated.
当然,您可以在compiles()
调用周围添加所有必要的宏,以便对其进行gwitness。当然,您必须在c编译器调用中设置命令行选项,以设置正确的路径和定义。 相关文章:
- 是否可以使C++类成为Objc类的委托
- 是否可以使一个类成为两个不同层次结构的子类?
- 是否有编译器标志可以使较新的 gcc 版本像旧版本一样构建
- C 可以使destuructor不称为班级成员和基类攻击方的灾难
- 可以使未命名的结构静态
- 是否可以使整数仅收到一个单个数字而不是两个接收输入
- C++:有哪些常规方法可以使代码更有效地用于大数字
- 是否可以使 std 容器使用默认运算符为新?
- LD_BIND_NOW可以使可执行文件运行得更慢?
- 是否可以使头文件使文本居中?- 在控制台中
- 有什么方法可以使核心忙碌等待
- 有没有一种技术可以使虚函数在所有派生类中强制重写?
- 有没有一种方法可以使全局函数/静态成员函数一次可呼出
- 是否有一种方法可以使此C 14递归模板在C 17中短
- 编写一个可以使二维数组平坦的函数
- 有哪些优化技巧可以使我的代码运行得更快
- 有没有更好的方法可以使此代码线程安全?线程局部静态似乎是一个生硬的工具
- 如果必须在同一向量上写入线程,是否可以使用线程
- 对于具有两个模板化变量的模板化类,是否可以使一个 var 引用另一个 var
- C 中的内容可以使Windows 8应用程序不在手臂上运行