C++ 你能检测到不可编译的代码吗?

C++ 你能检测到不可编译的代码吗?,c++,sfinae,static-assert,C++,Sfinae,Static Assert,在单元测试中,我们有以下几行代码: // Should not compile - manually checked // auto val = ::Utils::LexicalCast<const char*>(5); //不应编译-手动检查 //auto val=::Utils::LexicalCast(5); 事实上,如果我取消注释这段代码,它将在静态断言的LexicalCast中失败: static_assert(!std::is_pointer<ToType>

在单元测试中,我们有以下几行代码:

// Should not compile - manually checked
// auto val = ::Utils::LexicalCast<const char*>(5);
//不应编译-手动检查
//auto val=::Utils::LexicalCast(5);
事实上,如果我取消注释这段代码,它将在静态断言的LexicalCast中失败:

static_assert(!std::is_pointer<ToType>::value, "Cannot return pointers from a LexicalCast");
static_assert(!std::is_pointer::value,“无法从LexicalCast返回指针”);
在这种情况下,不清楚谁拥有内存

我的问题是,使用任何高级C++特性(我主要是想sfina,但是我不太精通它),有可能检查函数中调用的STATICHYSART是否会编译某些东西吗?我不介意在运行时或编译时进行检测,也不介意宏等,因为这些都是测试

编辑:例如,我想要像这样的东西

ASSERT_DOESNT_COMPILE(::Utils::LexicalCast<const char*>(5));
ASSERT\u不编译(::Utils::LexicalCast(5));

也许太明显了,但如果您只对这个特定(静态断言)案例感兴趣,您可以简单地将其重新定义为其他内容:

#include <cassert>
#include <cstdio>
using namespace std;

#define static_assert(flag, msg) { assert(flag); }

int main()
{
    static_assert(false, "static_assert compile time");

    return 0;
}
#包括
#包括
使用名称空间std;
#定义静态_断言(标志,消息){assert(标志);}
int main()
{
静态断言(false,“静态断言编译时”);
返回0;
}

以下示例显示SFINAE无法帮助执行
静态\u断言

#include <type_traits>

// Fall back version that will always compile
template<class T>
void foo(T) {}

// Specific version using a static_assert that may or may not fire
template<class T>
void foo(T*) {
    static_assert(std::is_same<T, char>::value, "Boo");
}

int main(int argc, char** argv) {
    // This could call the fall back version, but the static_assert fires anyway
    foo((int*)0);
    return 0;
}
#包括
//将始终编译的回退版本
模板
void foo(T){}
//使用可能触发或不触发的静态断言的特定版本
模板
void foo(T*){
静态断言(std::is_same::value,“Boo”);
}
int main(int argc,字符**argv){
//这可能会调用回退版本,但静态_断言仍然会触发
foo((int*)0);
返回0;
}

当使用clang++(3.4)和g++(4.8.1)编译时,
static_assert
会启动,尽管根据SFINAE,它不应该启动。我的结论是SAFIAE,即静态断言失败是一个错误

简单案例:提供有条件地启用代码不同部分的定义。然后有一个“测试驱动程序”,它使用不同的定义运行编译器,并检查编译器是否在应该的时候失败。您可能还想查看boost,我认为库中有类似的测试(编译/不编译)。从单元测试运行编译器(exe或lib),并检查结果?您能检测到不可编译的代码吗?是>试着编译它,如果它失败了,它是不可编译的。我很欣赏所有这些编译和检查的答案,但这将涉及到对单元测试框架的重新调整,所以我真的更喜欢在正常的成功构建和运行流中发生这样的事情。虽然这可能不可能。也许我遗漏了什么,但是如果
静态断言失败,您的代码将无法编译。如果您的代码未编译,您如何对其运行单元测试?抱歉,-1。从语言的角度来看,这是非法的,如果在函数体之外使用静态断言(这是可能的,因为它是一种声明类型)。这实际上是一个有趣的选项,所以我尝试了一下-不幸的是,代码在静态断言之后没有编译,因此,即使将此设置为运行时故障(例如,通过在#define中引发异常),我仍然无法意识到这是不正确的(重新定义关键字),但例如,GCC对此没有问题。为什么“如果在函数体之外使用静态断言,那么它根本不起作用”?显然,您必须尽早重新定义它,但在单元测试中,您可以完全控制环境,这应该是可能的。Mike,您能举个例子吗?@proxi
static\u assert
也可以用在
struct
的主体中,而旧的C
assert
只能在函数中使用,因为它是运行时的东西。当然,您可以用
std::enable\u if
替换所有的
static\u assert
s,并尝试为此构建一些SFINAE构造,但这意味着您禁止使用语言特性,因此不太可取。我认为您唯一的选择是编写一个脚本,该脚本尝试编译所有不应编译的表达式,并断言编译器返回的每个表达式都有一个错误。我认为这不值得努力,但你可以比我更好地判断这一点。