簡體   English   中英

標准::對<auto, auto>返回類型

[英]std::pair<auto, auto> return type

我在std::pair玩弄auto 在下面的代碼中,函數f應該返回依賴於模板參數的std::pair類型。

一個工作示例:

例 1

template <unsigned S>
auto f()
{
    if constexpr (S == 1)
        return std::pair{1, 2}; // pair of ints
    else if constexpr (S == 2)
        return std::pair{1.0, 2.0}; // pair of doubles
    else
        return std::pair{0.0f, 0.0f}; // pair of floats
}

這適用於 gcc 9.2、gcc 10.0、clang 9.0 和 clang 10.0。

接下來,為了清晰起見,我想將返回類型顯式寫為std::pair

例2

template <unsigned S>
std::pair<auto, auto> f()
{
    if constexpr (S == 1)
        return {1, 2};
    /* ... */
}

gcc 9.2/10.0 和 clang 9.0/10.0 都無法編譯這個。

海灣合作委員會 9.2

error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return

從最后一條錯誤消息來看,gcc 9.2 似乎認為std::pair<auto, auto>是一個int 這怎么解釋?

海灣合作委員會 10.0

error: returning initializer list

這個錯誤是可以理解的,但是,我希望調用std::pair的構造函數,或者我在這里遺漏了什么?

叮當 9.0 和 10.0

'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'

好吧,clang 不喜歡這些。 從第二條錯誤消息來看,似乎 clang 也認為返回類型是int

最后,為了修復使用 gcc 10.0 編譯時出現的錯誤,我決定明確返回一個std::pair

例3

template <unsigned S>
std::pair<auto, auto> f()
{
    if constexpr (S == 1)
        return std::pair{1, 2};
    /* ... */
}

叮當 9.0 和 10.0

和以前一樣,但有一個額外的:

no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'

這里 clang 仍然認為我們正在返回一個int

海灣合作委員會 9.2

和之前一樣。

海灣合作委員會 10.0

有用!

我想某些功能仍然需要實現,或者在上述一種情況下,是否有一個正確的編譯器和另一個錯誤的編譯器? 在我看來,示例 2 應該有效。 或者不應該?

語法:

std::pair<auto, auto> f() { return std::pair(1, 2); }
~~~~~~~~~~~~~~~~~~~~~

是原始概念 TS 的一部分,但未包含在作為 C++20 一部分的概念提案中。 因此,C++20 中唯一的占位符類型是auto (及其變體,如auto** )、 decltype(auto)和受約束的占位符( Concept auto及其變體)。 這種嵌套的占位符類型非常有用,但不是 C++20 的一部分,因此函數聲明是格式錯誤的。

現在,gcc 允許它,因為 gcc 實現了概念 TS,我猜他們決定保留這個功能。 clang 從未實現過 TS,所以它沒有。

無論哪種方式,這:

std::pair<auto, auto> f() { return {1, 2}; }

永遠是畸形的。 語法的含義是我們推導出返回類型,然后要求它與某些類型TU pair<T, U>匹配。 我們基本上是在嘗試調用發明的函數:

template <typename T, typename U>
void __f(std::pair<T, U>);

__f({1, 2}); // this must succeed

但是您不能從{1, 2}推導出類型 - 花括號初始化列表沒有類型。 也許這是應該探索的事情(因為至少在這樣的簡單案例中很容易理解),但從未被允許。 因此,無論哪種方式,拒絕它都是正確的。

最后:

gcc 9.2 似乎相信std::pair<auto, auto>是一個int 這怎么解釋?

出於某種原因(可能是由於我們的 C 遺留的隱式int ),當 gcc 無法識別或理解類型時,它只是使用int作為錯誤消息中的占位符。 這非常令人困惑,因為顯然是 gcc 提出了int而不是源代碼。 但事情就是這樣。

暫無
暫無

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

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