簡體   English   中英

類模板實例化和通用引用

[英]Class template instantiations and universal references

在這樣的代碼中:

template<class...> struct pack{};

template<class, class = int>
struct call_t
{
    template<class... args_t>
    static int apply(args_t&&...)
    { return 0; }
};

template<class... args_t>
struct call_t<pack<args_t...>, // (1)
        std::decay_t<decltype(convert(declval<args_t>()...))> >
{
    template<class... params_t> // (2)
    static int apply(params_t&&... args)
    { return convert(std::forward<params_t>(args)...); }
};

template<class... args_t>
auto test(args_t&&... args) // (3)
{
    return call_t<pack<args_t...> >::
       apply(std::forward<args_t>(args)...);
}

該函數根據函數convert存在而向函數或其他函數發送一組參數,並且可以使用傳遞的參數調用,保持完整(我猜)它們的確切傳遞類型,並且當其返回類型為int ,與參考無關或const限定符。

我對這段代碼有三個疑問。

  • (1) declval返回類型仍然是一個普遍的參考? 例如, declval<T>() ,其中T = int& ,它的返回類型是int&& (一個真正的r值引用),或int & &&並再次推導為int&並且在傳遞給通用引用時遵循通常的規則另一個電話? 我認為它沒有(正如@ 101010所指出的那樣),但在這種情況下我不知道如何進行完美的重載測試。

  • (2)我是否需要重新指定可變參數模板以使用通用引用推導規則,或者由於已經在(3)中推導出了正確的類型,它們是否保持其推導類型完整無缺?

或者我可以寫

template<class... args_t>
struct call_t<pack<args_t...>, // (1)
        std::decay_t<decltype(convert(declval<args_t>()...))> >
{
    // (2)
    static int apply(args_t... args)
    { return convert(args...); }
};

call_t模板類是一個實現細節,因此,它將僅在test內實例化。

這兩種情況並不相同。 這個例子:

template<class... args_t>
struct call_t<pack<args_t...>, // (1)
        std::decay_t<decltype(convert(declval<args_t>()...))> >
{
    // (2)
    static int apply(args_t... args)
    { return convert(args...); }
};

不轉發任何東西。 參數包args...是左值,因為它們有名稱。 這與此代碼非常不同:

template<class... params_t> // (2)
static int apply(params_t&&... args)
{ return convert(std::forward<params_t>(args)...); }

其中args... 轉發。 由此產生的行為是新示例可能比舊示例慢(執行副本而不是移動),或者只是令人驚訝地無法編譯。 考慮convert(std::unique_ptr<int> ) 使用args_t = {std::unique_ptr<int>} ,但是內部的apply()會失敗,因為你試圖復制unique_ptr

你需要這樣做:

static int apply(args_t... args)
{ return convert(std::forward<args_t>(args)...); }

暫無
暫無

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

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