type - template parameters c++




O argumento padrão do modelo perde seu tipo de referência (2)

Para foo<int>(a) , ARG_T está sendo deduzido de a e não é retirado do argumento do modelo padrão. Como é um parâmetro da função by value e a é uma expressão do tipo int , é deduzido como int .

Em geral, os argumentos padrão do modelo não são usados ​​quando a dedução do argumento do modelo pode descobrir qual é o argumento.

Mas podemos forçar o uso do argumento padrão, introduzindo um contexto não deduzido para o parâmetro de função. Por exemplo:

template <class T, class ARG_T = T&>
T foo(std::enable_if_t<true, ARG_T> v1){
    //...
}

Ou o utilitário type_identity do C ++ 20, como a outra resposta demonstra.

Considerar

#include <iostream>
#include <type_traits>

template <class T, class ARG_T = T&>
T foo(ARG_T v){
    return std::is_reference<decltype(v)>::value;
}

int main() {
    int a = 1;
    std::cout << foo<int>(a) << '\n';
    std::cout << foo<int, int&>(a) << '\n';
}

Eu esperaria que a saída fosse 1 em ambos os casos. Mas, no primeiro caso, é 0: consistente com o padrão sendo a class ARG_T = T em vez da class ARG_T = T& .

o que estou perdendo?


Você precisa interromper a dedução do argumento do modelo para ARG_T partir do argumento da função v (com a ajuda de std::type_identity , que pode ser usada para excluir argumentos específicos da dedução); Caso contrário, o argumento do modelo padrão não será usado. por exemplo

template <class T, class ARG_T = T&>
T foo(std::type_identity_t<ARG_T> v){
    return std::is_reference<decltype(v)>::value;
}

LIVE

BTW: Se o seu compilador não suportar std::type_identity (desde C ++ 20), você poderá criar o seu próprio.

template<typename T> struct type_identity { typedef T type; };
template< class T >
using type_identity_t = typename type_identity<T>::type;




argument-deduction