2011-12-15 22 views
9

Tôi đang sử dụng gcc 4.4 trên Debian squeeze. Hãy xem xét mã sau đây.Các tham số mẫu tiêu bản và mẫu variadic với gcc 4.4

#include <map> 
#include <string> 
using std::map; 
using std::string; 

// Args lets the user specify additional explicit template arguments 
template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
C<T, Args...> foo() 
{ 
    C<T, Args...> x; 
    return x; 
} 

int main(void) 
{ 
    map<string, int> a = foo<string, map, int>(); 
} 

Vì vậy, ý tưởng ở đây là T trận string, C trận map, và tham số mẫu gói Args trận int. Tôi có thể có một số cú pháp sai, xin vui lòng sửa nếu có. Cụ thể, nếu một người muốn đối số mẫu đầu tiên trong class C để khớp với T và phần còn lại để khớp với gói thông số mẫu Args, là template <typename T, typename... Args> class C cú pháp chính xác?

này cung cấp cho các lỗi

In function 'int main()': 
post.cc:18: error: no matching function for call to 'foo()' 

này dường như là tương tự như câu hỏi Variadic template templates and perfect forwarding. Câu hỏi đó cho thấy đây là lỗi gcc, nhưng có lẽ tôi đã nhầm lẫn khi nghĩ rằng những câu hỏi này cũng giống nhau.

Hãy nhẹ nhàng. Kiến thức của tôi về các mẫu variadic là ít hơn 12 giờ tuổi; Tôi đã cố gắng để viết lại một số mã C + + cũ để giảm trùng lặp. Nó cũng đã được một thời gian kể từ khi tôi đã làm bất kỳ C + +. Nếu có giải pháp thay thế, vui lòng cho tôi biết. Cảm ơn.

CHỈNH SỬA: Cách giải quyết được đề xuất trong các nhận xét của Variadic template templates and perfect forwarding bởi Ise Wisteria đã làm việc cho tôi, điều này cho thấy rằng đây là lỗi giống nhau. Tất nhiên, tôi bây giờ là (a) tự hỏi làm thế nào mong manh workaround này là và (b) tại sao nó hoạt động, và những gì thúc đẩy Ise nghĩ về nó. Mặc dù tôi đoán chỉ có Ise mới có thể trả lời câu hỏi cuối cùng. :-)

+0

Mã biên dịch trên g ++ 4.7. Nên là một lỗi. – kennytm

+0

@KennyTM: Cảm ơn. Điều đó có nghĩa là tôi không cần phải báo cáo, đúng không? –

+0

Phải. ~~~~~~~~~~ – kennytm

Trả lời

3

Như đã thảo luận trong các chỉnh sửa, câu hỏi của tôi dường như cù lỗi tương tự như các câu hỏi liên quan, Variadic template templates and perfect forwarding. Đặc biệt, giải pháp được đưa ra trong liên kết cũng hoạt động trong trường hợp của tôi. Mã được sửa đổi hoạt động như sau:

#include <map> 
#include <string> 
using std::map; 
using std::string; 

template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
struct X 
{ 
    typedef C<T, Args...> type; 
}; 

template <typename T, 
     template <typename T, typename... Args> class C, 
     typename... Args> 
typename X<T, C, Args...>::type foo() 
{ 
    C<T, Args...> x; 
    return x; 
} 

int main(void) 
{ 
    map<string, int> a = foo<string, map, int>(); 
} 
0

Tôi không nghĩ rằng các tham số mẫu có thể phù hợp với các đối số không phải là giá trị trong g ++ 4.4, vì vậy bạn cần phải quá tải hàm foo của mình với phiên bản không phải là phiên bản.

Cũng nên nhớ rằng bản đồ thực sự có nhiều hơn hai tham số mẫu và cũng không phù hợp với hàm foo mới.

Ngoài này để dụ bạn nên làm rõ nó:

#include <map> 
#include <string> 
using std::map; 
using std::string; 

// Args lets the user specify additional explicit template arguments 
template <typename T, 
      template <typename T, typename... Args> class C, 
      typename... Args> 
C<T, Args...> foo() { 
    C<T, Args...> x; 
    return x; 
} 

template<typename T, template<typename, typename> class C, typename Arg> 
C<T, Arg> foo() { 
    return C<T, Arg>(); 
} 

template<typename T, typename... Args> class A {}; 

template<typename T, typename Arg> class B {}; 

int main(void) { 
    map<string, int> a = foo<string, map, int>(); // fails. 
    A<string, int> x = foo<string, A, int>(); 
    B<string, int> y = foo<string, B, int>(); 
} 
+0

Không, mẫu variadic rõ ràng có thể khớp với mẫu không biến đổi. – Xeo

+0

@Xeo: Không phải trên g ++ 4.4 – masaers

+0

Vâng, đó là một lỗi. Tôi đang nói về những gì tiêu chuẩn nói."Tôi không nghĩ rằng các tham số mẫu có thể khớp với các đối số không phải là biến thể" có vẻ như cho thấy rằng bạn nghĩ đây là trường hợp nói chung. – Xeo