2013-10-03 125 views
0

我遇到了一個非常棘手的C++編譯器錯誤。std :: string構造在參數

當我構造一個字符串作爲參數使用時,它在調用常規方法時起作用。例如。 printThisString(string(charPtr));

構建對象時,如果構造函數的參數是char*,它不起作用。例如,MyObject a(string(argv[0]));如果參數是文字,它仍然有效。例如,MyObject b(string("hi"));

#include <iostream> 
#include <string> 

using namespace std; 

void printString(string toPrint) { 
    cout << toPrint << endl; 
} 

class MyObject { 
    int blah; 
public: 
    void aMethod() {} 
    MyObject (string myStr) { 
     cout << myStr << endl; 
    } 
}; 

int main(int argc, char ** argv) { 

string s1(argv[0]); 
char * s2 = "C-style string"; // I realize this is bad style 

printString(string("Hello world!")); // All of these work 
printString(s1); 
printString(string(s2)); 
printString(string(argv[0])); 

MyObject mo1 (string("Hello world!")); // Valid 
MyObject mo2 (s1); // Valid 
MyObject mo3 (string(s2)); // Does not print 
MyObject mo4 (string(argv[0])); // Does not print 

mo1.aMethod(); 
mo2.aMethod(); 
mo3.aMethod(); // Error 
mo4.aMethod(); // Error 


return 0; 
} 

對於M03和MO4,對象可以被創建,但也可以使用任何方法。他們是錯誤的典型。看來,編譯器認爲他們是功能...

test.cpp: In function 'int main(int, char**)': 
test.cpp:22:13: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] 
test.cpp:36:5: error: request for member 'aMethod' in 'mo3', which is of non-class type 'MyObject(std::string) {aka MyObject(std::basic_string<char>)}' 
test.cpp:37:5: error: request for member 'aMethod' in 'mo4', which is of non-class type 'MyObject(std::string*) {aka MyObject(std::basic_string<char>*)}' 
+2

歡迎C++,最讓人頭疼的解析家的問題。 – chris

+0

您使用支持C++ 11的編譯器嗎? – goji

+0

這就是爲什麼你應該更喜歡'Type variable = ...;'聲明。賦值被省略了,所以它歸結爲類型變量(...);'減去模糊性。 (假設構造函數不是'explicit',否則你必須寫'Type variable = Type(...);'但它又會產生相同的代碼) – syam

回答

1

這只是一個most vexing parse的變化:mo3mo4是函數聲明,而不是對象定義。您可以修復使用

MyObject mo3 {string(s2)}; 
MyObject mo4 {string(argv[0])}; 

MyObject mo3 ((string(s2))); 
MyObject mo4 ((string(argv[0]))); 

MyObject mo3 = MyObject(string(s2)); 
MyObject mo4 = MyObject(string(argv[0])); 

或...

+0

或'MyObject mo2(static_cast (s2));'。但是我提倡反對類似'string(s2)''的函數式C類轉換是否太詭異? ;-) –

+0

這很有道理。我仍然想知道這些對象的工作原理。 mo4是一個返回一個MyObject實例的函數,但它的參數是什麼? g ++說它唯一的參數是'string *',但string(argv [0])如何能夠命名一個類型? – user2503216

+0

@ user2503216:請參閱我對上述問題的評論。在參數列表中,字符串(argv [0])與字符串argv [0]相同,這是一個有效的參數聲明,其含義與'string * argv'相同。 –

相關問題