Tôi nghĩ rằng lý do đằng sau lỗi này là do thực tế rằng các đối số mặc định trong hàm mẫu áp dụng cho chuyên môn của nó là tốt và bạn không được phép xác định đối số mặc định nhiều hơn một lần trong C++.
xem xét như sau:
#include <iostream>
template<class T> void f(T t = 'a') {}
template<> void f<char>(char c)
{
std::cout << c << std::endl;
}
int main(int argc, char **argv)
{
f<char>();
}
này sẽ in a
nghĩa là chuyên môn hoá được gọi với đối số mặc định xác định trong mẫu chính.
Nếu bạn cần một đối số mặc định khác nhau cho từng chuyên ngành bạn có thể sử dụng phương pháp này minh họa dưới đây:
#include <iostream>
template<class T>
struct default_arg
{
static T get() { return T(); }
};
template<class T> void f(T t = default_arg<T>::get()) {}
template<>
struct default_arg<char>
{
static char get() { return 'a'; }
};
template<> void f<char>(char c)
{
std::cout << c << std::endl;
}
int main(int argc, char **argv)
{
f<char>();
}
Nhận xét nhỏ: bạn không cần dấu chấm phẩy sau khi định nghĩa hàm. – vitaut
Không thực sự trả lời câu hỏi, nhưng nó sẽ không được sạch hơn/dễ dàng hơn để sử dụng quá tải thay vì chuyên môn? Đối với một cuộc thảo luận về quá tải và chuyên môn hóa, xem các bài viết này từ Herb Sutter: [Bài báo của người dùng C/C++] (http://www.gotw.ca/publications/mill17.htm) và [GotW # 49] (http://www.gotw.ca/gotw/049.htm). –
+1 đến @Luc. Nếu bạn chỉ làm 'void f (char c = 'a') {}' nó biên dịch hoàn toàn tốt. –