推断声明的类型
Deduce the type of a declaration
我正在编写一个将声明作为其单个参数的宏。是否可以 推断宏内部声明 的类型而不将单个参数拆分为单独的 type 和 identifier 参数?
#define M(declaration) \
declaration; \
static_assert(sizeof(/* deduce type of 'declaration' */) == 4, "!")
M(int i);
M(double d{3.14});
M(std::string s{"Hello, world!"});
以下实现可行,但感觉不太用户友好 (imo):
#define M(type, identifier) \
type identifier; \
static_assert(sizeof(type) == 4, "!")
M(int, i);
M(double, d{3.14});
M(std::string, s{"Hello, world!"});
如果可能的话,我更愿意将声明作为一个参数。
相关问题: Macro to get the type of an expression;但我没能在我的示例中使用该代码(编译器错误:expected nested-name-specifier)。
如果您的静态断言消息真的那么简单"!"
1,我建议您放弃预处理器。让类型系统为你工作:
namespace detail {
template<typename T>
struct check_declared_type {
using type = T;
static_assert(sizeof(type) == 4, "!");
};
}
template<typename T>
using M = typename detail::check_declared_type<T>::type;
// .. Later
int main() {
M<int> i;
M<double> d{3.14};
M<std::string> s{"Hello, world!"};
}
1 - 具体来说,如果您不需要预处理器为您字符串化任何内容。
这个宏应该适用于您的所有示例,但它确实有一个严重的问题:
#define M(declaration) \
declaration; \
do { \
struct dummy__ { declaration; }; \
static_assert(sizeof(dummy__) == 4, "!"); \
} while (false)
问题是 class 定义中的初始化程序必须在顶层使用 =
标记或花括号初始化列表,而不是在顶层使用括号。因此,例如 M(SomeClass obj(true, 3));
将无法编译,即使 sizeof(SomeClass)==4
也是如此。由于大括号初始化器并不完全等同于括号初始化器,这意味着某些声明将无法与宏一起使用。
我正在编写一个将声明作为其单个参数的宏。是否可以 推断宏内部声明 的类型而不将单个参数拆分为单独的 type 和 identifier 参数?
#define M(declaration) \
declaration; \
static_assert(sizeof(/* deduce type of 'declaration' */) == 4, "!")
M(int i);
M(double d{3.14});
M(std::string s{"Hello, world!"});
以下实现可行,但感觉不太用户友好 (imo):
#define M(type, identifier) \
type identifier; \
static_assert(sizeof(type) == 4, "!")
M(int, i);
M(double, d{3.14});
M(std::string, s{"Hello, world!"});
如果可能的话,我更愿意将声明作为一个参数。
相关问题: Macro to get the type of an expression;但我没能在我的示例中使用该代码(编译器错误:expected nested-name-specifier)。
如果您的静态断言消息真的那么简单"!"
1,我建议您放弃预处理器。让类型系统为你工作:
namespace detail {
template<typename T>
struct check_declared_type {
using type = T;
static_assert(sizeof(type) == 4, "!");
};
}
template<typename T>
using M = typename detail::check_declared_type<T>::type;
// .. Later
int main() {
M<int> i;
M<double> d{3.14};
M<std::string> s{"Hello, world!"};
}
1 - 具体来说,如果您不需要预处理器为您字符串化任何内容。
这个宏应该适用于您的所有示例,但它确实有一个严重的问题:
#define M(declaration) \
declaration; \
do { \
struct dummy__ { declaration; }; \
static_assert(sizeof(dummy__) == 4, "!"); \
} while (false)
问题是 class 定义中的初始化程序必须在顶层使用 =
标记或花括号初始化列表,而不是在顶层使用括号。因此,例如 M(SomeClass obj(true, 3));
将无法编译,即使 sizeof(SomeClass)==4
也是如此。由于大括号初始化器并不完全等同于括号初始化器,这意味着某些声明将无法与宏一起使用。