std :: make_array常用类型的基本原理

use*_*963 5 c++ c++17

std :: make_array使用公共类型.但是,我的主要问题是它允许代码编译,否则将无法编译:

template <typename T>
void foo(T a, T b)
{
}

int main()
{
    auto arr = std::experimental::make_array(1, 3.0); // Compiles
    foo(1, 3.0); // a and b types must match
    std::array<int, 2> arr2{1, 3.0}; // narrowing conversion
}
Run Code Online (Sandbox Code Playgroud)

这不一定是坏事.但我发现它不一致.请注意,由于模板参数推导的工作方式,std::make_array<int>实际上禁用了推导(因为您明确指定了类型),因此无法解决问题.

在这里使用普通类型的理由是什么?

Dan*_*our 1

std::make_array使用普通类型。

它还应该使用什么来推断要创建的数组元素的类型?

第一个元素?如果是这样的话,那岂不是很矛盾……

auto a = make_array(1, 3.0);
auto b = make_array(3.0, 1);
Run Code Online (Sandbox Code Playgroud)

...这两个的不同类型的数组?

当然,可以认为 SFINAE 或static_assert传递的参数的所有类型都是相同的,但随后您人为std::make_array限制了该函数的使用。考虑:

short x = 3;
auto c = make_array(x, 42); // Should this be a compiler error? I'd say no ...
Run Code Online (Sandbox Code Playgroud)

您可以更进一步,将类型“相同”的要求放宽为(在某种意义上)兼容的类型。但话说回来,你不是已经完成一半以上了std::common_type……吗?

(可能)官方推理(N3824)是其目的是提供“类元组”接口和“类数组”接口。前者的行为类似于std::make_tupleorstd::make_pair并推导出一些合适的(因此常见的)类型,后者反映了原始数组声明,例如...

int arr[] = {1, 2, 3};

...它不会推断出元素的类型,而只会推断出数组长度。