Giả mã sau:quá tải bất ngờ gọi khi hàm được gọi từ mẫu variadic instantiation
#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]
Cuộc gọi cuối cùng - foo(a)
, nơi a
là char[4]
- gọi là phiên bản tôi mong đợi - template<unsigned N> void foo(const char (&)[N])
. Nhưng tại sao không mô phỏng mẫu variadic của foo
gọi foo(const char (&)[N]
, nhưng thay vào đó hãy gọi foo(const char *)
? Nếu không có quá tải mảng char, điều đó sẽ được mong đợi - nhưng tại sao nó lại xảy ra ở đây? Không nên const First &
chụp loại mảng đúng cách?
Ngoài ra, cách dễ nhất để làm cho phiên bản variadic chung hoạt động đúng với các mảng được truyền cho nó là gì?
Như Matthieu M. nhận thấy trong các ý kiến, vấn đề có lẽ không phải là do mẫu variadic, nhưng bởi indirection:
#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 *
Ông cũng nói rằng nó có thể là trình biên dịch bug - mặc dù mã này mang lại kết quả giống hệt nhau trong cả hai công cụ Clang 3.2 dev, G ++ 4.6 và 4.7.
R. Martinho Fernandes lưu ý rằng việc thay đổi a
's gõ vào đoạn cuối cùng để const char a[]
làm cho năng suất đang const char *
hai lần.
Tại sao '// fine; "afas" là const char * '? Không phải vậy! http://ideone.com/4KewDe –
@ R.MartinhoFernandes, cố định. – Griwes
Tôi đã quản lý để giảm thêm vấn đề [ở đây] (http://liveworkspace.org/code/72b3963b4f0c2d00592b4ce00f08fc82). Rõ ràng là sự vô hướng đang gây ra vấn đề và variadic không có gì để làm với điều này. Tuy nhiên vẫn chưa tìm thấy một lời giải thích có khả năng ... Nó chắc chắn trông giống như một lỗi trình biên dịch với tôi. –