gpt4 book ai didi

c++ - std::pair 返回类型

转载 作者:行者123 更新时间:2023-12-01 09:09:17 36 4
gpt4 key购买 nike

我在玩autostd::pair .在下面的代码中,函数 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 都无法编译这个。

gcc 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 .这怎么解释?

gcc 10.0
error: returning initializer list

这个错误是可以理解的,但是,我期望 std::pair 的构造函数被调用,还是我在这里遗漏了什么?

clang 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};
/* ... */
}

clang 9.0 和 10.0

和以前一样,但有一个额外的:
no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'

这里 clang 仍然认为我们正在返回 int ?

gcc 9.2

和之前一样。

gcc 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 实现了 Concepts TS,我猜他们决定保留此功能。 clang 从未实现过 TS,所以它没有。

无论哪种方式,这:
std::pair<auto, auto> f() { return {1, 2}; }

永远是不正确的。语法的意思是我们推导出返回类型,然后要求它匹配 pair<T, U>。对于某些类型 TU .我们基本上是在尝试调用发明的函数:
template <typename T, typename U>
void __f(std::pair<T, U>);

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

但是你不能从 {1, 2} 中推断出一个类型。 - 一个花括号初始化列表没有类型。也许这是应该探索的东西(因为至少在这样的简单案例中很容易理解),但它从未被允许。因此,无论哪种方式拒绝它都是正确的。

最后:

gcc 9.2 seems to believe that std::pair<auto, auto> is an int. How can this be explained?



出于某种原因(可能是由于我们的 C 遗留带有隐式 int ),当 gcc 无法识别或理解类型时,它只使用 int作为错误消息中的占位符。这非常令人困惑,因为显然是 gcc 提出了 int而不是源代码。但事实就是这样。

关于c++ - std::pair<auto, auto> 返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59578575/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com