c++ - 不允许使用非成员函数重载 C++ 转换运算符的理由是什么

标签 c++ operator-overloading c++11

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);
}

并将该转换用作任何其他转换。

有关问题的更完整描述,请参阅 here或者在我的 Boost.Conversion 上图书馆..

所以问题是:不允许使用非成员函数重载 C++ 转换运算符的理由是什么?

最佳答案

根据当前规则,要确定是否可以在两个类之间进行转换,您只需查看两个地方:源定义和目标定义。如果您可以将转换定义为非成员函数,则转换函数可以在任何地方,这可能会使查找不需要的或不明确的转换的原因变得更加困难(除了使编译器更努力地工作以在转换发生的所有情况下找到可能的转换)需要或可能,例如运算符重载)。

我认为您提议的模板不太实用。尽管您可以在确实有适当的特殊情况的情况下明确地将其专门用于转换,但它仍然会捕获所有其他转换,从而导致与任何预先存在的转换产生歧义。

这可能是不允许此类转换的两个潜在因素。

关于c++ - 不允许使用非成员函数重载 C++ 转换运算符的理由是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2733459/

相关文章:

c++ - std::bind 占位符的重载运算符

c++ - 无法将空的初始值设定项分配给 unique_ptrs 的 vector

c++ - 基本类型的 std::vector 的部分类模板特化

c++ - 重载基本数据类型

c++ - 使用动态内存分配重载 istream 运算符

c++ - 在 C++ 中创建和实现类

C++ 模板继承

java - 在什么情况下网络爬虫可能会受到 CPU 限制而不是 IO 限制?

c++ - Visual Studio 无法 'see' 我包含的头文件

c++ - 在实时 Fedora 上编译 C++ 程序的命令