使用字符串文字构造对象

时间:2017-06-10 12:20:02

标签: c++ string constructor initialization string-literals

我有以下课程:

#include <iostream>
#include <string>

using namespace std;

class CLS
{
   int value;
   string str_value;

public:

    CLS(int param) { value = param; }

    CLS(string param)
    {
       str_value = param;
    }
};

int main()
{
    CLS a(2);
    CLS b = 3;
    CLS c("4");
    CLS d = "5";  // Error: invalid conversion from 'const char*' to 'int'
}

我搜索了没有运气的错误原因。

使用字符串文字构造是否正确? 如果不是,为什么? 如果是的话,我的代码出了什么问题?

我正在使用gcc 5.3和Code :: Blocks 16.1。

2 个答案:

答案 0 :(得分:11)

首先,"4"不是std::string,而是const char[2]。然后

CLS c("4");direct initialization,我们会检查CLS的构造函数是否初始化c。这里会选择CLS::CLS(string),因为const char[]可以通过用户定义的转化(即std::string)隐式转换为std::string::string(const char*)

CLS d = "5";copy initialization

(强调我的)

  
      
  • 如果T是类类型,并且other类型的cv-nonqualified版本不是T或来自T,或{{1} }}是非类型,但T的类型是类类型,用户定义的转换序列,可以从other的类型转换为other (或者T派生的类型,如果T是类类型并且转换函数可用),则检查并通过重载决策选择最佳的类型。
  •   

这意味着需要用户定义的转换序列才能将T转换为const char[2]。即使CLS也可以转换为const char[]std::string也可以转换为std::string,但只允许在一个implicit conversion sequence中进行一次用户定义的转换。这就是它被拒绝的原因。

(强调我的)

  

隐式转换序列按以下顺序组成:

     

1)零个或一个标准转换序列;
    2)零或一个用户定义的转换;
    3)零个或一个标准转换序列。

顺便说一句:如果你把它改为使用CLS作为初始化表达式,那么它就可以正常工作了。 e.g。

std::string

答案 1 :(得分:8)

CLS a(2); 
CLS b = 3;
CLS c("4");
CLS d = "5";

ac初始化为direct initialisation。另一方面,bd使用copy initialisation

不同之处在于,对于复制初始化,编译器会搜索(单个)用户定义的转换(在d的情况下)char const *(这有点不准确,请参见答案结束) CLS,而对于直接初始化,尝试了所有构造函数,其中CLS(std::string)可以使用,因为可以使用转换std::string(char const *)

<强>详情:

"5"是(C)字符串文字。它的类型是char const [2]。首先,搜索用户定义的从该类型到CLS的转换。由于找不到任何内容,因此会应用从Type[N]Type *Type = char constN = 2)的标准转换,在char const *中。然后编译器尝试查找用户定义的转换为CLS。因为它找不到一个,并且没有更多可以尝试的标准转换,编译失败。