繁体   English   中英

为什么文字运算符不能正常模板化?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM