【发布时间】:2020-04-22 00:25:40
【问题描述】:
我在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 编译失败。
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 应该有效。还是不应该?
【问题讨论】:
标签: c++ c++17 constexpr auto std-pair