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

Vic*_*iba 5 c++ operator-overloading c++11

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

当所需转换的Source和Target类彼此独立时,Source既不能定义转换运算符,也不能定义来自Source的构造函数.

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

Target ConvertToTarget(Source& v);
Run Code Online (Sandbox Code Playgroud)

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

template < typename To, typename From >
operator To(const From& val);
Run Code Online (Sandbox Code Playgroud)

例如,我们可以专门从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);
}
Run Code Online (Sandbox Code Playgroud)

并将转换用作任何其他转换.

有关该问题的更完整描述,请参阅此处或我的Boost.Conversion 库.

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

CB *_*ley 5

根据当前规则,要确定是否可以在两个类之间进行转换,您只需要查看两个位置:源定义和目标定义.如果您可以将转换定义为非成员函数,则转换函数可能位于任何可能使查找不需要或模糊转换的原因更加困难的地方(除了使编译器更难以在转换所有情况下找到可能的转换)需要或可能的例如操作员超载).

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

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