Justification for the standard type std :: make_array

std :: make_array uses a generic type. However, my main problem is that it allows you to compile code that otherwise would not be compiled:

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
}

This is not necessarily a bad thing. But I find this inconsistent. Note that due to how the output of the template argument works, it std::make_array<int>actually disables the output (because you explicitly specified the type) so as not to solve the problem.

What is the point of using a generic type here?

+4
source share
2 answers

std::make_array uses a generic type.

What else should be used to display the type of elements of the created array?

? , ...

auto a = make_array(1, 3.0);
auto b = make_array(3.0, 1);

... ?

, 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 ...

, "" , ( ) . std::common_type...?

(, (N3824) , "" , "" . std::make_tuple std::make_pair - ( , ) , raw , ...

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

... , .

+1

, , .

, . , , . , std::is_same :

template <typename T, typename... Args>
constexpr auto make_array(Args&&... args) -> std::array<T, sizeof...(Args)>
{
    static_assert((std::is_same<std::remove_cv_t<T>, std::decay_t<Args>>{} && ...), 
                  "arguments shall be of same type.");
    return {{std::forward<Args>(args)...}};
}

int main()
{
    auto a = make_array<int>(1, 2, 3);

    // ↓ error: static_assert failed "arguments shall be of same type."
    //auto b = make_array<int>(1, 2, 3.f);
}

1, 2 3 int, . , . float, , is_same<int, float> false.

std::make_array , (, make_array<int>), . .

, , , .

0

Source: https://habr.com/ru/post/1674868/


All Articles