2017-05-19 91 views
-1

什麼是傳遞NULL字符串的函數,而無需創建一個變量的正確方法? 我看到編譯錯誤與下面的代碼,我不希望改變的定義。也可能需要更改字符串,因此不想將其標記爲常量類型。傳遞空字符串函數作爲參數

#include <iostream> 
#include <string> 

using namespace std; 
void 
myfunc(int i, string &my) { 
    if (my.empty()) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << my <<endl; 
    } 
} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    std::string str2 (""); 
    myfunc(2, ""); 
    return 0; 
}` 

my1.cpp:18:錯誤:的類型的非const引用初始化無效 '的std :: string &' 從臨時類型的 '爲const char *' my1.cpp:6:錯誤:在經過論證2「無效MYFUNC(INT,的std :: string &) 」

繼編譯,但我不希望創建局部變量

#include <iostream> 
#include <string> 

using namespace std; 
void 
myfunc(int i, string &my) { 
    if (my.empty()) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << my <<endl; 
    } 
} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    std::string str2 (""); 
    myfunc(2, str2); 
    return 0; 
} 
+1

你通過引用傳遞意味着傳遞變量的地址而不是值。如果你想通過價值。 – Raindrop7

+0

引用通常以僞裝的形式實現爲指針,但這不是標準所要求的。 ** IS **要求的是參考實際上引用了一個適當的對象。 –

+0

@ Raindrop7,我們有沒有辦法通過引用字符串而不創建對象? – Tectrendz

回答

3

這裏的解決方案是不具有字符串參數的重載。

void myfunc(int i, string &my) { 
     cout << "String is " << my <<endl; 
} 

void myfunc(int i) { 
    cout << "Empty" << endl; 
} 

int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2); 
} 

這是最簡單明瞭的解決方案,準確地傳達你的意圖和功能。

,因爲如果你要修改的參數,則該參數應該是「非const引用」,所以它不能綁定到臨時變量你不應該嘗試做它自己的方式。因此你不能傳遞字符串到它。


如果你想讓它明確,你不傳遞一個字符串,你可以創建翼nullptr標籤,雖然我不建議額外的複雜性時,上述變化是明確和被大家理解,在乍一看。

struct no_string_tag_t {}; 
constexpr no_string_tag_t no_string_tag; 

void myfunc(int i, string &my) { 
     cout << "String is " << my <<endl; 
} 

void myfunc(int i, no_string_tag_t) { 
    cout << "Empty" << endl; 
} 

int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2, no_string_tag); 
} 

如果你真的想要一個單一的功能,那麼語義正確的版本將有一個可選的參考。

auto foo(int i, std::optional<std::reference_wrapper<std::string>> my) 
{ 
    if (my) 
     cout << "String is " << my <<endl; 
    else 
     cout << "no string" << endl; 

} 
int main() 
{ 
    std::string str1 ("Test string"); 
    myfunc(1, str1); 
    myfunc(2, std::nullopt); 
} 

如果你想保持函數簽名,並且仍然能夠傳遞給它一個臨時的,那麼你的運氣了。C++有一個安全功能,因爲它不允許非常量綁定到臨時綁定。這個限制的原因是,嘗試通過引用來修改一個臨時對象很可能是bug,而不是程序員的意圖,因爲臨時消失了。

0

你不能傳遞一個臨時的非-const參考參數ameter。該對象是臨時的,只要函數返回就會被銷燬。函數對該對象所做的任何更改都將丟失。

如果你想有修改字符串的機會,你可以通過const引用的字符串,返回修改後的字符串。

string myfunc(int i, string const &s); 
: 
str1 = myfunc(1, str1); 
auto result2 = myfunc(2, ""); 

您的其他選擇是使用指向可以爲空的字符串的指針。

void myfunc(int i, string *s) { 
    if (!s) { 
     cout << "Empty" << endl; 
    } else { 
     cout << "String is " << *s <<endl; 
    } 
} 

myfunc(1, &str1); 
myfunc(2, nullptr); 
相關問題