假设bad_name
是受限制的标识符,例如我不想成为结构的一部分。我正在寻找一种机制来强制在这种情况下编译失败。
example.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;
}
有可能通过模拟反射在运行时导致失败,但有没有办法在编译时执行此操作?
答案 0 :(得分:4)
您可以将bad_name
定义为会导致编译时错误的内容。例如,什么都没有:
#define bad_name
给出GCC
错误:声明没有声明任何内容[-fpermissive]
int bad_name;
答案 1 :(得分:4)
您可以在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
这种技术的优点是错误信息可以提醒您问题是什么(即使有点模糊)。
更新阅读this后,如果数组大小为负,我发现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,这将更加清晰。
答案 2 :(得分:1)
您可以使用以下内容:
#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, "");
答案 3 :(得分:0)
假设bad_name是受限制的标识符,例如我不是 想成为结构的一部分。我正在寻找一种强制机制 在这种情况下编译失败。
这不是完全可移植的,但至少在VC ++和GCC中,您可以将标识符标记为deprecated,如果需要,可以提升它给出的错误警告。