是否可以将带有字符串化运算符的宏转换为 constexpr?
Is it possible to convert a macro with stringizing operator to a constexpr?
我编写了以下宏来模仿 C# 的nameof
运算符,但在 C++/CLI 中:
#define nameof(x) (#x)
if (info == nullptr)
throw gcnew ArgumentNullException(nameof(info));
我试图将此宏转换为constexpr
:
其中任何一个都是错误的,它们返回ToString
的内容:
template <typename T>
constexpr auto NAMEOF1(T value)
{
return """" + value + """";
}
template <typename T>
constexpr auto NAMEOF2(T value)
{
return System::String::Format("{0}", value);
}
第三次尝试,使用typeid
关键字:
template <typename T>
constexpr auto NAMEOF3(T value)
{
return gcnew System::String(typeid(value).name());
}
但它失败并显示以下错误:
错误 C3185:"typeid":用于托管类型"T",改用"T::typeid">
简而言之,并不像听起来那么容易。
问题:
是否可以将此宏名称转换为constexpr
?
(或者我应该坚持旧的#define
?
不,不可能在constexpr
函数中获取C++对象的名称。constexpr
函数仍然可以在运行时调用,而在运行时,没有这种反射的可能性。事实上,C++的反思总体上是极其有限的。如果没有宏,您的反射能力仅限于使用肮脏和不直观的模板技巧测试成员的存在和类型,但不会以字符串形式返回名称。还要注意的是,一旦将参数传递给像NAMEOF1
这样的函数,该参数的名称将始终"value"
。无法查询调用方的范围以获取传递的名称或表达式。
您应该坚持使用您的解决方案:
#define nameof(x) (#x)
当然,这也是一个非常有限的解决方案。这只会将表达式x
完全逐字转换为字符串,并且没有像 C# 中的nameof
那样具有不同实体和作用域的概念。
我说这是来自非管理C++背景。从您收到的错误消息中可以清楚地看出,托管C++对typeid
有有趣的影响。也许对 C++/CLI 有更多了解的人可以启发我或给出更好的答案。
或者,如果这种 null 检查是一种常见的模式,则可以将其包装到更简洁的宏中。例如:
define THROW_IF_NULL(x)
if ((x) == nullptr){
throw gcnew ArgumentNullException(#x);
}
用法示例:
void process_info(Info* info){
THROW_IF_NULL(info)
// --snip--
}
一方面不是,我不确定你期望这样做做什么:
return """" + value + """";
但是,如果我的理解是正确的,表达式""""
将被解析为两个空字符串文字(""
、""
(,因为它们并排出现,所以由预处理器附加到单个空字符串文字中。因此,您可以将""""
替换为""
以达到相同的效果。但也许你想要别的东西?
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 是否可以将带有字符串化运算符的宏转换为 constexpr?
- 将INT32BE宏转换为 constexpr 是否正确?
- Boost.Hana:在 constexpr 上下文中将值元组转换为相应类型的元组
- 将 'hana::string' 转换为 'constexpr const char (&)[]'
- constexpr 链表 - 从 const X* 到 X* 的转换无效
- 转换运算符,它引用类模板参数和 constexpr 类成员
- 将 constexpr 结构转换为运行时结构
- 为什么 constexpr 隐式转换并不总是有效?
- 指向数据成员转换的 Constexpr 指针
- 在 C++11 中将静态 constexpr 数组转换为模板参数
- 将结构转换为 constexpr 数组uint8_t
- 子类ConstexPR类以获得不同的用户定义的转换行为
- 我可以将C 17 Capture lambda ConstexPR转换操作符的结果用作函数指针模板非类型参数吗?
- 将variadic模板转换为constexpr
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 编译时类型转换检查(constexpr和用户定义的文字)
- 如何将模板大小的数组初始化转换为 constexpr 初始化
- 通过显式转换函数初始化枚举类类型的静态constexpr类成员
- 将代码转换为 constexpr