Why is it impossible to introduce a concept for outputting a type of specifier if the same restriction should output different types?

We have:

template <typename ...T> concept bool Numerics = ( std::is_arithmetic_v<T> && ... ) ;
template <typename T>    concept bool Numeric  =   std::is_arithmetic_v<T>;

Then we let the compiler print all the numbers:

template <typename T, typename U, typename V, typename W> requires Numerics<T,U,V,W>
auto foo(T arg1, U arg2, V arg3, W arg4) {
    return 0.0 + arg1 + arg2 + arg3 + arg4;
}

std::cout << foo (1,2.0,3.0f,4.0l) << "\n";

The compiler prints all types of arguments as expected:

auto foo<int, double, float, long double>(int, double, float, long double):

When we try to distribute the constraints in the type specifier to write a shorter version:

auto foo2(Numeric arg1, Numeric arg2, Numeric arg3, Numeric arg4) {
    return 0.0 + arg1 + arg2 + arg3 + arg4;
}

Although, the compiler was unable to do this unexpectedly:

// err: deduction fails
//
// std::cout << foo2(1,2,3,4.0) << "\n"; 

It seems that the compiler will try to deduce everything into the same type, which does not work here.

Why? Should the compiler derive different types from the same constraint?

Live

+4
source share
1 answer

This is one of the most controversial aspects of TS concepts. When you say

template <typename T> concept bool C = true;

template <C T, C U>
void func(T t, U u);

it is translated as if you said

template <typename T, typename U> requires (C<T> && C<U>)
void func(T t, U u);

, " ",

void func(C t, C u); 

,

template <typename T> requires C<T>
void func(T t, T u);

, .

TS, ++ 20, . , 20-, , - .

+7

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


All Articles