簡體   English   中英

采用參數包的兩個函數的重載分辨率

[英]Overload resolution for two functions taking parameter packs

請考慮以下兩個重載:

template<typename T, typename ...Args>
void f(std::vector<T>&& v, Args&& ...args)
{
    std::cout << "f taking a vector + parameter pack\n";
}

template<typename ...Args>
void f(Args&& ...args)
{
    std::cout << "f taking a parameter pack\n";
}

現在,對於以下片段,選擇了預期的重載:

std::vector<int> v{1, 2, 3};
f(std::move(v), 3.0);

(輸出: f采用矢量+參數包

對於以下情況,選擇第二個重載:

std::vector<int> v{1, 2, 3};
f(v, 3.0);

(輸出: f參數包

通用參考矢量參數也綁定到左值參考 那么為什么只有參數包的重載在這種情況下受到青睞呢? 更新:請參閱接受的答案,假設向量參數是通用/轉發引用是錯誤的。

通用參考矢量參數也綁定到左值參考

不,這不是一個普遍的參考

4)如果P是對cv非限定模板參數的右值引用(所謂的“轉發引用”),並且相應的函數調用參數是左值,則使用對A的類型左值引用代替A進行推導(注意:這是std :: forward動作的基礎注意:在類模板推導中類模板的模板參數永遠不是轉發引用(因為C ++ 17)):

因此對於

template<typename T, typename ...Args>
void f(std::vector<T>&& v, Args&& ...args)

請注意, v不是模板參數T的右值引用,而是std::vector<T> 所以v是“只是”一個右值引用,然后不能綁定到左值。

正如接受的答案所解釋的那樣:

該向量不被視為轉發參考(又稱通用參考)。

(編譯器知道它是一個向量,因此這部分沒有模板引用推論,這意味着雙符號 - && - 被視為對未知類型T的向量的右值引用)。

但是,如果我們確實希望將矢量視為轉發參考?

如果您希望將矢量作為轉發參考傳遞,您可以執行以下操作:

template<typename T> struct is_vector : public std::false_type {};

template<typename T, typename A>
struct is_vector<std::vector<T, A>> : public std::true_type {};

// [1] the special case
// the vector becomes now just V and acts as Forwarding Reference
// the enable_if ensures that we deal with V that is a vector
template<typename V, typename ...Args>
typename std::enable_if<
    is_vector<std::remove_const_t<std::remove_reference_t<V>>>::value
>::type
f(V&& v, Args&& ...args) {
    std::cout << "f taking a vector + parameter pack\n";
}

// [2] the generic case
template<typename ...Args>
void f(Args&& ...args) {
    std::cout << "f taking a parameter pack\n";
}

int main() {
    // all cases below go to the 1st overload
    std::vector<int> v1{1, 2, 3};
    f(v1, 3);

    const std::vector<int> v2{1, 2, 3};
    f(v2, 3);

    f(std::vector<int>{1, 2, 3}, 3);

    // this goes to the 2nd overload
    std::array<int, 3> a{1, 2, 3};
    f(a, 3);
}

暫無
暫無

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

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