在这个问题中:
我们有一些关于如何让典型的 C++ 编译器在编译时打印类型名称的建议。然而,它们依赖于触发编译错误。
我的问题:我可以让 C++ 编译器在不停止编译的情况下打印类型的名称吗? 一般来说,答案是“可能不是”,因为一个有效的程序可以编译到其目标对象中,而无需在任何地方打印任何内容,所以我特别询问 GCC 和 clang,可能使用预处理器指令、编译器内置函数或任何编译器特定的技巧。
备注:
显然,挑战在于在
using/typedef
#message "my type is unsigned long long"
的内容(如 @NutCracker 建议的那样)。但这不是问题所在。依赖 C++11 或更早版本的答案优先于需要 C++14/17/20 的答案。
这给你:
<source>: In function 'void __static_initialization_and_destruction_0(int, int)':
<source>:7:55: warning: call to 'your_type_was_<int>' declared with attribute warning: type printed for your convenience [-Wattribute-warning]
7 | #define print_type_of(_x) your_type_was_<decltype(_x)>()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
<source>:9:10: note: in expansion of macro 'print_type_of'
9 | bool b = print_type_of(i);
| ^~~~~~~~~~~~~
查看它
正在从事 Godbolt。
[[deprecated]]
template<typename T>
[[deprecated]] inline constexpr void print_type(T&& t, const char* msg=nullptr){}
print_type(999, "I just want to know the type here...");
<source>:32:59: warning: 'constexpr void print_type(T&&, const char*) [with T = int]' is deprecated [-Wdeprecated-declarations]
print_type(999, "I just want to know the type here...");
与已接受的答案相反,这适用于每个符合 c++17 的编译器。请注意,您必须在 MSVC 上启用 \W3`。
我们甚至可以更进一步,定义一个静态断言宏,当且仅当失败时才会打印类型。
template<bool b, typename T>
inline constexpr bool print_type_if_false(T&& t) {
if constexpr (!b)
print_type(std::forward<T>(t));
return b;
}
// Some nice static assert that will print the type if it fails.
#define STATIC_ASSERT(x,condition, msg) static_assert(print_type_if_false<condition>(x), msg);
是一个活生生的例子。