簡體   English   中英

可變參數模板模板的完美轉發

[英]Perfect forwarding of variadic template templates

我目前正在使用一些新的C ++ 17功能,特別是std::optional ,並且我決定可以使用可變參數模板模板來提出最小查找功能。 這是我到目前為止的內容:

template <template <typename> typename Opt, 
          typename T>
Opt<T> optional_min(Opt<T>&& opt) {
    return std::forward<Opt<T>>(opt);
}

template <template <typename> typename Opt0,
          template <typename> typename Opt1,
          template <typename> typename... Opts, typename T >
std::common_type_t<Opt0<T>, Opt1<T>, Opts<T>...> 
optional_min(Opt0<T>&& opt0, Opt1<T>&& opt1, Opts<T>&&... opts) {
    if (!opt0 && !opt1) 
    {
        return optional_min(std::optional<T>(std::nullopt), std::forward<Opts<T>>(opts)...);
    } 
    else if (opt0 && !opt1) 
    {
        return optional_min(opt0, std::forward<Opts<T>>(opts)...);
    } 
    else if (!opt0 && opt1) 
    {
        return optional_min(opt1, std::forward<Opts<T>>(opts)...);
    } 
    else 
    {
        return (*opt0 < *opt1) ? 
            optional_min(opt0, std::forward<Opts<T>>(opts)...) 
                : optional_min(opt1, std::forward<Opts<T>>(opts)...);
    }
}

int main() {
    std::optional<int> a = 9;
    std::optional<int> b = std::nullopt;
    std::optional<int> c = 4;

    if (auto x = optional_min(a, b, c)) 
        std::cout << *x << std::endl;

    return 0;
}

看來我的轉發不起作用。 我對轉發的想法還不陌生,所以我可能會錯過一些愚蠢的事情。 我得到的錯誤是這樣的:

error: no matching function for call to 'optional_min(std::optional<int>&, std::optional<int>&, std::optional<int>&)'

error: cannot bind rvalue reference of type 'std::optional<int>&' to lvalue of type 'std::optional<int>'
  auto x = optional_min(a, b, c);

我的編譯器還告訴我,我的可變參數optional_min函數僅是一個緊密匹配項,並且它正在嘗試與我的另一個optional_min函數進行匹配,即該函數僅接受一個參數。 有誰知道為什么會這樣? 如果您需要了解更多信息,請告訴我。

optional_min的參數都不是轉發參考。 它們都是右值引用。

當您將參數聲明為對推導的模板類型參數的右值引用時,就會形成轉發引用,但實際情況並非如此。 optional_min的參數是對推導的模板模板參數的實例化的右值引用。

為了避免這種情況,剛擺脫了Opt0Opt1Opts直接模板的模板參數,並使用類型參數:

template <typename Opt0, typename Opt1, typename... Opts>
auto optional_min(Opt0&& opt0, Opt1&& opt1, Opts&&... opts) {
    //...
}

如果這是您的目標,則可以使用SFINAE將類型參數限制為std::optional實例化。

暫無
暫無

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

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