推断声明的类型
Deduce the type of a declaration
我正在编写一个将声明作为其单个参数的宏。是否可以在不将单个参数拆分为单独的类型和标识符参数的情况下推断宏内声明的类型?
#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!"});
如果可能的话,我宁愿将声明作为一个单一的论点。
相关问题:宏来获取表达式的类型;但我未能使该代码在我的示例中工作(编译器错误:预期的嵌套名称说明符)。
如果你的静态断言消息真的那么简单"!"
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)
问题在于,类定义中的初始值设定项必须在顶级使用 =
标记或大括号 init-list,而不是在顶层使用括号。 因此,例如M(SomeClass obj(true, 3));
不会编译,即使sizeof(SomeClass)==4
. 由于大括号初始值设定项不完全等同于括号初始值设定项,这意味着某些声明将无法与宏一起使用。
相关文章:
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 如何使用自定义类型声明Arduino数组?
- 将函数参数类型声明为 auto
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 在没有标识符的情况下如何读取复杂的C++类型声明?
- 模板函数参数显式类型声明
- 使用指针遍历一系列基元类型声明?
- 字符类型声明和验证
- 使用本地类型声明的G lambda被使用但从未定义 - 确实是一个错误
- 为什么 c++ lambda 捕获不需要类型声明?
- 为什么没有"int"类型声明时输出不同?
- C++如何使用虚拟基类型声明全局静态分配的变量
- 我可以使用预处理器将一个类型声明替换为另一个类型声明吗?
- 如何将数据类型声明从.cpp文件传输到 .cu 文件
- C++17 枚举类型声明
- 条件类型声明
- 具有特定参数的特定构造函数的类型声明
- 我可以使用相同的名称为周围作用域中的类型声明成员类型别名吗
- 函数调用之前,C 类型声明