1

我的课是这样的:

class X {

public:
        :
        :
        :
  operator const char*() const { return "foo"; };
  operator std::string() const { return std::string( "foo" ); };
        :
        :
        :
};

我希望能够像这样隐式地初始化 std::string ,但是会出现大量错误:

string s1( x );

甚至明确地不起作用:

string s1( (string) x );

但是将 x 转换为(const char*)工作正常:

string s1( (const char*) x );

除了你们拥有的任何解决方案之外,还有任何其他建议来制作一种应该可以自由转换为 C 样式字符串和std:string?(我已经有用于 Xconst char*std::stringx 的构造函数,并且可以这些类型中进行赋值。

4

1 回答 1

0

我不确定我的解释是否 100% 准确,但如果不是,希望有人会澄清它。为了简单起见,我将使用自定义类来代替std::stringand :char*Yint

struct Y 
{
   Y(int) { }
};

struct X
{
   operator int() const { return 1; }
   operator Y() const { return Y(0); }
};

int main()
{
   X x;
   Y y(x);
}

使用此代码,在C++11/14中,编译器有两个选项如何继续:

  1. 它转换xY(0)byX::operator Y()然后将其传递Y(0)给 的移动构造函数Y

  2. 它转换xint(1)byX::operator int()然后将 this 传递int(1)给转换构造函数Y::Y(int)

这两个选项是等效的,因此会产生歧义,从而导致编译错误。


C++17中,由于保证复制省略,情况有所不同。在这里,省略了 (1.) 中移动构造函数的调用,因此选择了第一个转换序列,因为它只需要 1 次转换而不是 2 次。


无论如何,这个版本:

Y y(static_cast<Y>(x));

在 C++11/14 中也会产生歧义,我必须承认,我不明白。

于 2020-03-30T13:03:25.727 回答