pet*_*sev 9 c++ templates static-assert incomplete-type
有没有办法在标题中的那个点上使用static_assert类型T 不完整?如果有人在他们不应该的地方添加#includes,那么这个想法就会产生编译错误.
使用该链接的答案,
namespace
{
template<class T, int discriminator>
struct is_complete {
static T & getT();
static char (& pass(T))[2];
static char pass(...);
static const bool value = sizeof(pass(getT()))==2;
};
}
#define IS_COMPLETE(X) is_complete<X,__COUNTER__>::value
class GType;
static_assert(!IS_COMPLETE(GType),"no cheating!");
Run Code Online (Sandbox Code Playgroud)
不幸的是,这给出了"无效使用incomlete类型"错误,哦.有没有办法断言否定?
传递引用...不起作用。
5.2.2/7:
\n\n\n\n\n当给定参数没有参数时,参数的传递方式使得接收函数可以通过调用
\nva_arg(18.10) 来获取参数的值。[注意跳过 \xe2\x80\x94 nm] 对参数表达式执行左值到右值 (4.1)、数组到指针 (4.2) 和\n 函数到指针 (4.3) 标准转换。具有(可能cv- 限定)类型的参数std::nullptr_t将转换为类型void*(4.10)。在这些转换之后,如果参数没有算术、枚举、指针、成员指针或类类型,则程序格式错误。
这是一种根据 @chris 的评论匆忙改编的可行解决方案:
\n\n#include <iostream>\n#include <utility>\nnamespace\n{\n\n template<typename T, int>\n constexpr auto is_complete(int) -> decltype(sizeof(T),bool{}) {\n return true;\n }\n\n template<typename T, int>\n constexpr auto is_complete(...) -> bool {\n return false;\n }\n}\n\n\n#define IS_COMPLETE(T) is_complete<T,__LINE__>(0) // or use __COUNTER__ if supported\n\nstruct S;\n\nstatic_assert(IS_COMPLETE(int), "oops 1!");\nstatic_assert(!IS_COMPLETE(S), "oops 2!");\n\nstruct S {};\n\nstatic_assert(IS_COMPLETE(S), "oops 3!");\nRun Code Online (Sandbox Code Playgroud)\n