[英]Why can't the literal operator be templated normally?
我目前正在研究编译时表达式树,并希望使用文字运算符从文字创建表达式。 由于所有文字都被允许作为表达式,我想将文字运算符模板化,例如:
template <typename T>
constexpr auto operator""_ve(T value)
{
return value_expression(value);
}
这没有编译,所以我做了一些研究,发现唯一允许的模板是
template <char...> XYZ operator "" _abc();
这是为什么? 我真的必须手动指定每个重载吗?
我真的必须手动指定每个重载吗?
是的。
文字运算符不是通过重载解析调用的(不是真的)。 重载解析可以做一些事情,比如允许隐式转换或其他不愉快的事情。 因为文字运算符(通常)由编译器在编译时生成的值上调用,所以最好确保文字运算符的作者获得整个文字值(当然,编译器可以提供的最好) , 不是转换后的值。
这实际上非常重要。 考虑这样一种情况:您想编写一个采用整数值而不是浮点值的文字。 也就是说, 12.3_lit
应该是编译错误。 您的运算符签名将采用unsigned long long
,但long double
可隐式转换为unsigned long long
。 因此, 12.3_lit
在您不希望它是有效的时候是有效的。
现在理论上你可以通过= delete
显式地= delete
浮点签名来避免这种情况。 但是...... UDL 是在= delete
并不是真正的东西的时候发明的,所以这不一定是一种选择。
为了避免这些情况,文字运算符分派逻辑显式查找一组特定的签名(基于正在处理的文字类型)。 如果操作符没有long double
重载(或原始文字版本),那么在遇到12.3_lit
,系统将找不到合适的函数并生成编译错误。
因为系统搜索特定的签名而不是使用重载解析,所以文字运算符签名(包括模板)被限制为精确且仅是文字运算符分派逻辑将搜索的签名。 不多也不少。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.