C++ 不允许C++;具有非成员函数的转换运算符

C++ 不允许C++;具有非成员函数的转换运算符,c++,operator-overloading,c++11,C++,Operator Overloading,C++11,C++0x添加了显式转换运算符,但它们必须始终定义为源类的成员。这同样适用于赋值运算符,它必须在目标类上定义 当所需转换的源类和目标类彼此独立时,源类和目标类都不能定义转换运算符,目标类和源类都不能定义构造函数 通常我们通过定义一个特定的函数来获得它,比如 Target ConvertToTarget(Source& v); 例如,如果C++0x允许非成员函数重载转换运算符,我们可以隐式或显式地定义不相关类型之间的转换 template < typename To, typena

C++0x添加了显式转换运算符,但它们必须始终定义为源类的成员。这同样适用于赋值运算符,它必须在目标类上定义

当所需转换的源类和目标类彼此独立时,源类和目标类都不能定义转换运算符,目标类和源类都不能定义构造函数

通常我们通过定义一个特定的函数来获得它,比如

Target ConvertToTarget(Source& v);
例如,如果C++0x允许非成员函数重载转换运算符,我们可以隐式或显式地定义不相关类型之间的转换

template < typename To, typename From >
operator To(const From& val);
template
操作员至(常量自&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);
}
template
操作员boost::posix_时间::ptime(
const boost::chrono::time_point和from)
{
使用名称空间boost;
typedef chrono::time\u point time\u point\t;
typedef chrono::纳秒持续时间;
typedef duration_t::rep rep;
rep_t d=chrono::持续时间(
from.time_-since_-epoch()).count();
代表秒=d/100000000;
代表nsec=d%100000000;
返回posix_time::from_time_t(0)+
posix_时间::秒(静态_投射(秒))+
posix_时间:纳秒(毫微秒);
}
并将该转换用作任何其他转换

有关问题的更完整描述,请参阅我的库中的或


这样的问题是:对于非成员函数的C++转换操作符的不允许重载的原理是什么?

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

我认为你提议的模板不太实用。尽管您可以显式地将其专门化,以便在有适当的特例的情况下进行转换,但它仍然会捕获所有其他转换,从而导致任何预先存在的转换的歧义


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

如果
源代码
目的地
之间没有直接关系,那么我想明确地标识它们之间的转换,就像使用
源代码fromDestination(const Destination&)
函数一样,对于随机隐式转换也不必感到惊讶。

这不是一个答案,因为您的论证是主观的。我认为这对编译器来说不会更难。局部性问题是任何非成员函数固有的,这些函数可以针对特定类型进行专门化或重载。这并不排除C++具有非成员函数。例如,我们可以有一个通用的convert_to函数(参见)。当用户看到convert_to(y)时,转换也可以在任何地方。隐式转换的问题与转换是非成员函数这一事实无关,而是与它是隐式的这一事实有关。C++0x添加了显式转换运算符以解决此问题。当然,非成员转换运算符重载也可以是显式的,因此不需要的隐式转换没有问题。好的,不难,但计算成本更高。想象一个简单的调用,比如
T;U U;f(t,u)
如果有大量的
f()
重载,但没有一个是完全匹配的,那么使用自由函数转换运算符,转换可能性的数量可能会更快地增加。它可能是显式的,但是,如果你想要自由函数转换函数,你肯定希望它们也是隐式的,否则为什么不使用命名函数呢?