Предположим, что следующий код:
#include <iostream>
template<typename... T>
void foo(const T &...);
template<unsigned N>
void foo(const char (&)[N])
{
std::cout << "char(&)[N]" << std::endl;
}
void foo(const char *)
{
std::cout << "const char *" << std::endl;
}
template<typename T>
void foo(const T &)
{
std::cout << "Single" << std::endl;
}
template<typename First, typename... T>
void foo(const First & first, const T &... rest)
{
std::cout << "Generic + " << sizeof...(T) << std::endl;
foo(first);
foo(rest...);
}
int main()
{
const char * c = "asdf";
char a[] = {'a', 'b', 'c', 'd'};
foo('f', c, a, 1);
foo(a);
}
Generic + 3
Single // fine; 'f' is `char` -> generic
Generic + 2
const char * // fine; c is `const char *`
Generic + 1
const char * // (!) not fine
Single
char(&)[N] // fine; a is char[4]
Последний вызов - foo(a)
, где a
- char[4]
- вызывает версию, которую я ожидаю - template<unsigned N> void foo(const char (&)[N])
. Но почему не создается экземпляр вариационного шаблона foo
вызывает foo(const char (&)[N]
, а вызывает foo(const char *)
вместо этого? Если не было перегрузки массива char, этого следовало ожидать - но почему это происходит здесь? Должен ли const First &
правильно захватить массив?
Кроме того, что было бы самым простым способом сделать стандартную версию varadic правильной работой с переданными ей массивами?
Как заметил в комментариях Маттиу М., проблема, вероятно, не вызвана вариационными шаблонами, а косвенностью:
#include <iostream>
template <unsigned N>
void foo(const char (&)[N])
{
std::cout << "char(&)[N]" << std::endl;
}
void foo(const char *)
{
std::cout << "const char *" << std::endl;
}
template <typename T>
void goo(T const& t) {
foo(t);
}
int main()
{
char a[] = {'a', 'b', 'c', 'd'};
foo(a);
goo(a);
}
char(&)[N] const char *
Он также сказал, что это может быть ошибка компилятора - хотя код дает точно такие же результаты как в Clang 3.2 dev, g++ 4.6 и 4.7.
R. Martinho Fernandes отметил, что изменение типа a
в последнем фрагменте на const char a[]
приводит к удвоению кода const char *
.