不允许 C++ 重载的理由是什么?具有非成员函数的转换运算符
C++0x 添加了显式转换运算符,但它们必须始终定义为 Source 类的成员。这同样适用于赋值运算符,它必须在 Target 类上定义。
当所需转换的 Source 和 Target 类彼此独立时,Source 都不能定义转换运算符,Target 也不能从 Source 定义构造函数。
通常我们通过定义特定函数来获得它,例如
Target ConvertToTarget(Source& v);
如果 C++0x 允许通过非成员函数重载转换运算符,我们可以例如在不相关类型之间隐式或显式定义转换。
template < typename To, typename From >
operator To(const From& val);
例如,我们可以专门化从 chrono::time_point 到 posix_time::ptime 的转换,如下所示
template < class Clock, class Duration>
operator boost::posix_time::ptime(
const boost::chrono::time_point<Clock, Duration>& from)
{
using namespace boost;
typedef chrono::time_point<Clock, Duration> time_point_t;
typedef chrono::nanoseconds duration_t;
typedef duration_t::rep rep_t;
rep_t d = chrono::duration_cast<duration_t>(
from.time_since_epoch()).count();
rep_t sec = d/1000000000;
rep_t nsec = d%1000000000;
return posix_time::from_time_t(0)+
posix_time::seconds(static_cast<long>(sec))+
posix_time::nanoseconds(nsec);
}
,并将该转换用作任何其他转换。
有关问题的更完整描述,请参阅此处或我的Boost.Conversion 库..
所以问题是:什么不允许使用非成员函数重载 C++ 转换运算符的理由是什么?
C++0x has added explicit conversion operators, but they must always be defined as members of the Source class. The same applies to the assignment operator, it must be defined on the Target class.
When the Source and Target classes of the needed conversion are independent of each other, neither the Source can define a conversion operator, neither the Target can define a constructor from a Source.
Usually we get it by defining a specific function such as
Target ConvertToTarget(Source& v);
If C++0x allowed to overload conversion operator by non member functions we could for example define the conversion implicitly or explicitly between unrelated types.
template < typename To, typename From >
operator To(const From& val);
For example we could specialize the conversion from chrono::time_point to posix_time::ptime as follows
template < class Clock, class Duration>
operator boost::posix_time::ptime(
const boost::chrono::time_point<Clock, Duration>& from)
{
using namespace boost;
typedef chrono::time_point<Clock, Duration> time_point_t;
typedef chrono::nanoseconds duration_t;
typedef duration_t::rep rep_t;
rep_t d = chrono::duration_cast<duration_t>(
from.time_since_epoch()).count();
rep_t sec = d/1000000000;
rep_t nsec = d%1000000000;
return posix_time::from_time_t(0)+
posix_time::seconds(static_cast<long>(sec))+
posix_time::nanoseconds(nsec);
}
And use the conversion as any other conversion.
For a more complete description of the problem, see here or on my Boost.Conversion library..
So the question is: What is the rationale to non allow overloading of C++ conversions operator with non-member functions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据当前规则,要确定是否可以在两个类之间进行转换,您只需查看两个位置:源定义和目标定义。如果您可以将转换定义为非成员函数,则转换函数可以位于任何地方,这可能会使查找不需要的或不明确的转换的原因变得更加困难(此外,还使编译器更加努力地在转换发生的所有情况下找到可能的转换)需要或可能,例如运算符重载)。
我认为您提出的模板不太实用。尽管您可以在确实有适当的特殊情况的情况下显式地将其专门用于转换,但它仍然会捕获所有其他转换,从而导致任何预先存在的转换产生歧义。
这也许是不允许这种转换的两个潜在因素。
With the current rules, to work out whether you can convert between two classes you only need to look in two places: the source and target definitions. If you could define conversions as non-member functions the conversion function could be anywhere which might make finding the cause of unwanted or ambiguous conversions much more difficult (in addition to making the compiler work harder to find possible conversion in all cases where a conversion was need or possible e.g. operator overloading).
I don't think that your proposed template would be very practical. Although you could explicitly specialize it for conversion where you did have an appropriate special case, it would still catch all other conversions causing ambiguities with any pre-existing conversions.
These are perhaps two potential factors in not allowing such conversion.
如果
Source
和Destination
之间没有直接关系,那么我想显式标识它们之间的转换,就像使用Source sourceFromDestination(const Destination&)
函数,不要对随机隐式转换感到惊讶。If there's no direct relation between
Source
andDestination
, then I want to explicitly identify conversions between them, as with aSource sourceFromDestination(const Destination&)
function, and not be surprised by random implicit conversions.