如果存在具有特定名称的结构成员,则强制编译失败
Force compilation to fail if a struct member with a particular name exists
假设bad_name
是一个受限制的标识符,例如,我不想成为结构的一部分。在这种情况下,我正在寻找一种强制编译失败的机制。
示例.h
struct example {
int okay_name;
int bad_name;
}
main.cc
#include "example.h"
int main() {
example ex;
// cause compilation to fail here if bad_name is a member of ex
return 0;
}
可能有一些方法可以通过模拟反射在运行时导致失败,但有没有一种方法可以在编译时做到这一点?
您可以将bad_name
定义为会导致编译时错误的内容。例如,什么都没有:
#define bad_name
在GCC 上给出
错误:声明没有声明任何东西[-fpermission]
int bad_name;
您可以在C中模拟静态断言,如下所示:
#define bad_name xxx; char static_assertion_bad_name_used[-1];
struct example {
int okay_name;
int bad_name;
};
GCC中给出的是:
main.c:6: error: size of array ‘static_assertion_bad_name_used’ is negative
这种技术的优点是,错误消息会提醒您问题所在(即使有点模糊)。
更新阅读本文后,我发现如果数组大小为负数,MS Visual Studio不会在错误消息中包含实际变量名。这里有一个替代方案:
#define bad_name xxx; int static_assertion_bad_name_used : 0;
GCC中的错误消息是:
main.c:5: error: zero width for bit-field ‘static_assertion_bad_name_used’
显然在VS中也有类似的东西。
此外,如果使用最新的编译器,您可以使用_Static_assert,它会更干净。
您可以使用以下内容:
#include <cstdint>
#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)
template <typename U>
class traitsName
{
private:
template<typename T, T> struct helper;
template<typename T>
static std::uint8_t check(helper<signature, &funcName>*);
template<typename T> static std::uint16_t check(...);
public:
static
constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t);
}
DEFINE_HAS_SIGNATURE(has_bad_name, T::bad_name, decltype(&T::bad_name));
然后用static_assert
(需要C++11)进行检查:
static_assert(!has_bad_name<example>::value, "");
假设bad_name是一个受限制的标识符,例如我没有希望成为结构的一部分。我正在寻找一种机制来强制在这种情况下编译失败。
这不是完全可移植的,但至少在VC++和GCC中,您可以将标识符标记为不推荐使用,如果需要,还可以提升它向错误发出的警告。
相关文章:
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 包含模板文件的递归会导致编译失败
- 提升 1.64 单元测试编译失败
- 如何让谷歌测试正常运行。测试总是失败。(它不会编译)
- 运行时检查失败 #0 用于运行时重新编译
- C++模板的模板编译失败
- 使用已删除的函数进行编译失败,并显示 uclibc
- MinGW-w64 编译失败,nullptr_t
- 使用提升线程时编译失败
- 编译花絮 g++, clang++, 使用 libboost -- g++8 编译失败时 g++7 成功;
- 编译成功,使用 clang 5.0.1/6.0.0 ,在 5.0.2/6.0.1 时失败
- CMake + Qt,moc 编译失败,无法实现 QMetaObject 方法(编译器找不到基本 ui 对象的标头?
- 带有引用的std::tuple在clang中编译失败,但在gcc中编译失败
- bitbake-grpc交叉编译/配置失败,错误为c-ares::care引用文件/usr/lib/libcares.s
- 解决由于在哈希函数中使用了不完整的类型而导致的编译失败
- 将XCode升级到verison 11.1后,C++编译失败
- 继承的构造函数,在 clang++3.9 中编译,在 g++ 7 中失败
- C++:此代码可以编译,但引发运行时检查失败 #2 - 围绕变量周围的堆栈'num'已损坏。发生
- 添加类型名会导致程序编译失败
- 将 qi::lexeme 添加到灵气中的规则时编译失败