template<typename T1, size_t SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}
Você deve usar em std::size_t
vez de int
.
corra aqui
Edit:
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
em std::size_t
(porque eles são do tipo integral e a conversão implícita é muito trivial) e selecione a void 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:
Se um parâmetro de modelo que não seja do tipo for usado na lista de parâmetros e o argumento do modelo correspondente for deduzido, o tipo do argumento do modelo deduzido (conforme especificado em sua lista de parâmetros de modelo anexa, o que significa que as referências são preservadas) deve corresponder ao tipo do parâmetro exatamente o parâmetro de modelo não-tipo, exceto que os qualificadores cv são eliminados e exceto onde o argumento do modelo é deduzido de um limite de matriz - nesse caso, qualquer tipo integral é permitido, mesmo que seja sempre booleano:
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.
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::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo(b); // P = std::vector<std::array<int,(int)SIZE>
// A = std::vector<std::array<int,(unsigned_long)SIZE>>
// error: deduced non-type template argument does not have the same
// type as its corresponding template argument */
}
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.
#include <vector>
#include <array>
#include <iostream>
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::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});
foo<int,3>(b);
}
código de execução
vector
de todos eles. Veja aqui