gpt4 book ai didi

c++ - 是否可以使用 GTest 进行 ASSERT_DOES_NOT_COMPILE?

转载 作者:行者123 更新时间:2023-11-30 05:40:30 25 4
gpt4 key购买 nike

假设一个模板类,我们在编译时断言整数模板参数必须大于零:

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() 的调用周围添加所有必要的宏,以便对其进行 GTESTify。您当然必须在 c 编译器调用上设置命令行选项以设置正确的路径和定义。

关于c++ - 是否可以使用 GTest 进行 ASSERT_DOES_NOT_COMPILE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31607928/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com