2013-04-27 73 views
1

爲什麼彈出「.. \ src \ Test.cpp:30:9:錯誤:從const char [5] '非標量類型'測試'要求 「?錯誤:從'const char [5]'轉換爲C++中的非標量類型

但爲什麼在後續代碼中可以使用?

#include <iostream> 
using namespace std; 

class Test{ 

public: 
    string str; 

    Test(string str){ 
     this->str=str; 
     cout<<"constructor"<<endl; 
    } 

    Test(const Test &test){ 
     cout<<"copy constructor"<<endl; 
     this->str=test.str; 
    } 

}; 

int main() { 
    Test t=Test("test"); 
    return 0; 
} 
+0

@Petesh這是建設,而不是分配。 – 2013-04-27 13:09:49

+0

因爲字符串有一個const char *的默認構造函數。 – 2013-04-27 13:10:28

+0

誤讀了代碼,刪除了不準確的評論。感覺有點像製作評論的布偶 – Petesh 2013-04-27 13:12:12

回答

8
Test t="test"; 

此嘗試:

  • 轉換字符串文字(它是字符數組,char[5])到一個臨時string
  • 將暫時的string轉換爲Test

此失敗的原因有兩個:

  • 的隱式轉換的序列不能包含多於一個的用戶定義的轉換。這裏需要兩個。
  • 臨時無法綁定到非常量左值參考,這是您的轉換構造函數Test(string&)想要的。

你的第2例所解決這些問題:

  • 使得轉換從stringTest明確,Test(...)。現在只有一個隱式轉換,從char[5]string。請注意,這是一個詳細的初始化方式; Test t("test")會做同樣的事情。
  • 根據值聲明轉換構造函數採取string,而不是引用。常量引用const string&也可以工作,就像const char*一樣。

這兩個變化都是必須的,因爲每個修改都只修復了兩個問題中的一個。

+1

這總是困擾我,現在分配一個字符串文字,爲什麼編譯器會創建一個臨時的字符串對象?這是語言定義的東西嗎?並在創建對象時,如果obect重載了'='爲什麼它會觸發複製賦值構造函數而不是重載運算符? – 2013-04-27 13:22:22

+0

@Koushik:因爲'Test'唯一合適的構造函數(一旦它被固定爲一個值或'const'引用)需要一個字符串對象。如果有一個構造函數採用'const char *',那麼文字可以直接傳遞給那個,而不會創建臨時文件。 – 2013-04-27 13:24:43

+0

在你對另一個答案的評論中,你說const對string的引用不起作用,正如我在我的回答中所述。 [GCC同意](http://ideone.com/7YYR08),除非我錯過了一些東西。那麼是哪一個呢? – juanchopanza 2013-04-27 13:24:47

0

只要把const接受"test"這是一個常量文字:

Test(const string& str) : str(str) { 
    ^^^^^ 
} 

,並使用它像

Test t("test"); 

or 

Test t = string("test"); 

Live code

+1

您是否試過這樣做? [它不會工作](http://ideone.com/V6sU4n) – 2013-04-27 13:22:12

+0

@MikeSeymour它將在MSVC上,是的這是MS編譯器的缺陷,但我認爲他嘗試過。至少我做了,編譯沒有單一的警告。 – alexrider 2013-04-27 13:26:48

+0

呵呵,我忘了說怎麼調用它,更新 – deepmax 2013-04-27 13:31:52

1

你只能一個用戶定義類型之間的隱式轉換。您的代碼有從const char[6](其衰減到const char*)到std::string以及從std::stringTest的隱式轉換。這是將簽名更改爲Test(const std::string&)will not work的原因。

嘗試改變構造簽名

#include <string> 

struct Test 
{ 
    Test(const char* c) : s_(c) {} 
    std::string s_; 
}; 

int main() 
{ 
    Test t = "Hello"; 
} 
0

Test t =「test」; 編譯器會嘗試找到一個構造器:Test(const char *), 但你只是定義一個Test(字符串&),所以它彈出錯誤。

你可以嘗試定義構造函數,如測試(爲const char *)或修改您的代碼是這樣的:測試T =字符串(「測試」)

相關問題