C++ 无法转换<;字符串>;从‘;常量字符[]和#x2019;至<;类名>;

C++ 无法转换<;字符串>;从‘;常量字符[]和#x2019;至<;类名>;,c++,compiler-errors,C++,Compiler Errors,我有一个问题,涉及以下程序: class Player { public: Player(int new_id); private: string name; int id; }; class Team { public: Team(string new_name); private: Player* player; str

我有一个问题,涉及以下程序:

    class Player {
    public:
      Player(int new_id);
    private:
      string name;
      int id;
     };

     class Team {
        public:
          Team(string new_name);
        private:
          Player* player;
          string name;
        };

        int main()
        {
           Team a("Team1");
        }

        Team::Team(string new_name)
        {
           name=new_name;
           player= new Player[2]{1,2};
         }

        Player::Player(int new_id)
       {
          id=new_id;
       }
此程序可以工作,但当我将其更改为以下内容时:

    class Player {
    public:
      Player(string new_name);
    private:
      string name;
      int id;
     };

     class Team {
        public:
          Team(string new_name);
        private:
          Player* player;
          string name;
        };

        int main()
        {
           Team a("Team1");
        }

        Team::Team(string new_name)
        {
           name=new_name;
           player= new Player[2]{"Bob","Tom"};
         }

        Player::Player(string new_name)
       {
          name=new_name;
       }
它给了我这个错误:无法将“Bob”从“const char[4]”转换为“Player”。我不明白。我唯一改变的是我使用了字符串而不是int。有什么想法吗?
提前谢谢

>您的问题是关于用户定义的转换,如C++标准所规定的:

转换[class.conv]

类对象的类型转换可以由构造函数和 通过转换函数。这些转换称为用户定义的转换 转换和用于隐式类型转换(第7条),例如 初始化(11.6)和显式类型转换(8.4、8.2.9)

问题在于:

。。。最多一个用户定义的转换(构造函数或转换 函数)隐式应用于单个值

在您的工作示例中:

player= new Player[2]{1,2};
这里有一个用户定义的转换:
int
Player
,方法是使用
Player
的构造函数,该构造函数接受
int
参数

但在另一种情况下:

player= new Player[2]{"Bob","Tom"};
在这里,您需要进行两个用户定义的转换:使用其构造函数将文本字符字符串转换为
std::string
,然后使用
Player
的构造函数,该构造函数接受
std::string
参数。这里需要两个用户定义的转换。最多允许一个C++标准。失败

我只能想到两种可能的解决办法。一种是手动消除其中一种用户定义的转换:

player= new Player[2]{std::string{"Bob"}, std::string{"Tom"}};
现在只剩下一个用户定义的转换,使用构造函数从
std::string
转换为
Player

第二种解决方法是作弊,让玩家使用模板构造函数:

class Player {
public:
    template<typename Arg>
    Player(Arg &&arg)
        : name{std::forward<Arg>(arg)}
    {
    }
private:
    std::string name;
    int id;
};
职业玩家{
公众:
样板
播放器(Arg&&Arg)
:name{std::forward(arg)}
{
}
私人:
std::字符串名;
int-id;
};

这有效地接受了
Player
的构造函数的任何参数,将其中一个用户定义的转换向下推到字符串的构造函数。我想,我们可以在这里做一些改进,只有当
std::string
的构造成功时,才能让这个构造函数参与重载解析。这将需要更多的工作。

问题在于,在这个声明中

player= new Player[2]{"Bob","Tom"};
需要两个用户定义的隐式转换。第一个是将字符串文字转换为类型
std::string
,第二个是将类型
std::tring
的对象转换为类型Player。这是不允许的C++标准。< /P> 若要避免此错误,请向类中再添加一个构造函数。比如说

class Player {
public:
  Player( const std::string &new_name) : name( new_name ) {}
  Player( const char *new_name) : name( new_name ) {}
private:
  string name;
  int id;
 };
或者在不添加新构造函数的情况下,只需编写

player= new Player[2]{ Player( "Bob" ), Player( "Tom" ) };

当您说“我使用字符串而不是int”时,您的意思是“字符串”是指(以null结尾的)字符序列的一般概念,还是更具体地说是
std::string
?(相关,因为您在一个位置使用字符串文字,在另一个位置使用
std::string
)我的意思是std::string,那么您的声明是错误的。你不使用
std::string
而不是
int
来构建你的
播放器。你是什么意思?我应该使用什么?错误告诉您
“Bob”
的类型;它是
const char[]
,而不是
std::string
。您确定在这种情况下,Player-ctor调用是“转换”吗?我希望数组初始化器的每个部分都是
Player
的初始化器。也许情况并非如此。啊,这不是17.6.2.1,所以我们得到了副本初始化。这让我有点惊讶。