Eu tenho o seguinte código de modelo
#include <vector>
#include <array>
#include <iostream>
template<typename T1>
void foo(std::vector<T1> bar) {
std::cout << "GENERIC" << std::endl;
}
template<typename T1>
void foo(std::vector<std::vector<T1>> bar) {
std::cout << "SPECIFIC (vector)" << std::endl;
}
template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
int main() {
std::vector<std::vector<int>> a(2, std::vector<int> { 1, 2, 3});
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo(a);
foo(b);
}
que produz
SPECIFIC (vector)
GENERIC
Eu estou querendo saber por que a versão de vetor de vetor é chamada com o modelo específico, mas a versão de vetor de matriz é chamada com o genérico?
vector
de todos eles. Veja aquiRespostas:
Você deve usar em
std::size_t
vez deint
. corra aquiEdit: Na verdade, seus comentários e minha intuição sobre o código me levaram a aprofundar o assunto. À primeira vista, um desenvolvedor padrão (como eu) espera que o compilador seja convertido
int
emstd::size_t
(porque eles são do tipo integral e a conversão implícita é muito trivial) e selecione avoid foo(std::vector<std::array<T1, SIZE>> bar)
melhor especialização. Então, ao ler a página de dedução de argumento de modelo , encontrei o seguinte:Como sempre, é claro, você deve ler mais algumas vezes para entender o que significa :)
Então, um resultado interessante sai.
Nossa especialização desejada já não está selecionada, mas se o compilador tivesse sido forçado a selecionar, isso seria um erro.
código de execução
Outra coisa interessante é:
Se o argumento de modelo não-tipo não tivesse sido deduzido, não haveria restrição que force os tipos de argumento e modelo a serem os mesmos.
código de execução
fonte
size_t
...Eu acho que isso é simplesmente devido a uma linha de
[temp.deduct.call]/4
Para esclarecer,
A
significa o parâmetro, de[temp.deduct.call]/1
Como já foi apontado, alterar
template<typename T1, int SIZE>
paratemplate<typename T1, size_t SIZE>
corrigir o problema que você está vendo. Como afirmado em[temp.deduct.call]/4
, o compilador está procurando deduzir umA
que é idêntico aA
. Como umstd::array
argumento tem argumentos de modelo<class T, size_t N>
(de[array.syn]
), seu segundo parâmetro é de fatosize_t
, nãoint
.Portanto, para a dedução de modelo, sua função genérica
template<typename T1>
é capaz de corresponder exatamente ao tipo deA
, onde - como seu especialistatemplate<typename T1, int SIZE>
não é uma correspondência exata . Acredito que a MSVC esteja incorreta em sua dedução.fonte