簡體   English   中英

從一個函數返回的向量傳遞給另一個函數

[英]passing a vector returned from a function to another function

我有一個返回字符串向量的函數

std::vector<std::string> getNames()
{
std::vector<std::string> names;
names.push_back("one");
return names;
}

我有另一個帶有以下簽名的構造函數的類(實際上是來自TCLAP):

ValuesConstraint(std::vector<T>& allowed);

如果我嘗試執行以下操作,則會收到錯誤消息

ValuesConstraint<std::string> A( getNames() );

但是當我執行以下操作時

std::vector<std::string> v = getNames();
ValuesConstraint<std::string> A( v );

這發生在GCC 4.4.7中,但在VS2010中不發生。 錯誤如下:

error: no matching function for call to ‘TCLAP::ValuesConstraint<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::ValuesConstraint(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >)’

note: candidates are: TCLAP::ValuesConstraint<T>::ValuesConstraint(std::vector<T, std::allocator<_CharT> >&) [with T = std::basic_string<char, std::char_traits<char>, std::allocator<char> >]

note:                 TCLAP::ValuesConstraint<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::ValuesConstraint(const TCLAP::ValuesConstraint<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >&)

為什么會發生此錯誤,我該怎么做才能將返回值直接傳遞給構造函數?

為什么會發生此錯誤,我該怎么做才能將返回值直接傳遞給構造函數?

ValuesConstraint<>的構造函數接受一個左值(對非const的左值引用只能綁定到左值),而不返回引用類型的函數調用表達式為右值

左值引用不能綁定到右值,因此不能將臨時ValuesConstraint<>傳遞給ValuesConstraint<>的構造函數(臨時值是右值)。

如果您發現術語左值右值令人困惑,則可以(直觀地)認為 是:

  • 命名變量(實際上是標識符); 和/或
  • 對象(實際上是表達式)可以使用

它們通常表示具有穩定標識的可以在程序中重復引用的對象,從中隱式移動對象並不安全(因為以后可以在程序中引用它們)。

相反,您可以將右值視為:

  • 未命名的對象,例如臨時對象; 和/或
  • 文字(如42false3.14 ); 和/或
  • 表示具有“不穩定”身份的對象的表達式(例如std::move()的結果),這些對象將要從

他們通常指的是不能在程序中重復引用的對象(或對象,您承諾不通過顯式調用重新分配他們之前再引用std::move()並且,因此,安全地從移動。

不過,將上述內容帶入一粒鹽-這只是一個准則,您可以用來建立一些直覺來了解什么是價值類別,以及如何分辨某個表達式的價值類別。 用正式的術語來說,事情要復雜一些,上述概括並不總是正確的。

因此,在這種情況下,請回到您的示例:

std::vector<std::string> v = getNames();
//                       ^
//                       Named variable! Can take its address! lvalue!
ValuesConstraint<std::string> A( v );
//                               ^
//                               OK! The constructor accepts an lvalue
//                               reference to non-const, and I am giving
//                               it an lvalue

您正在將左值傳遞給構造函數,並且一切正常。 另一方面,在這種情況下:

ValuesConstraint<std::string> A( getNames() );
//                               ^^^^^^^^^^
//                               getNames() returns a vector by value, this
//                               means a temporary will be constructed as the
//                               return value of the function, and temporaries
//                               are unnamed... so, that's an rvalue!
//                               And the constructor accepts an lvalue reference
//                               to non-const! So this is an ERROR!

您試圖將右值傳遞給接受對非const左值引用的const (換句話說,它需要可修改的左值)。 那是非法的,編譯器對此有所抱怨。

這發生在GCC 4.4.7中,但不在VS2010中

那是因為VC10實現了一個不一致的編譯器擴展,該擴展允許將右值綁定到對非const左值引用。 請注意,這不是標准行為,如果您想編寫可移植的代碼,則不應依賴它(實際上,我建議您不要依賴它)。

正如Jesse Good在評論中所建議的那樣 ,將警告級別提高到4,以便從編譯器獲得警告並檢測使用此非標准擴展的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM