2015-08-30 21 views
5

Tôi hiện đang bị mắc kẹt trên một lỗi biên dịch, mà tôi thực sự không thể xác định ...Lỗi khi gọi một chức năng tích mẫu thành viên với g ++ và kêu vang ++

Dưới đây là một ví dụ làm việc tối thiểu:

#include <iostream> 

template <typename T, int R> 
class a_type 
{ 
public: 
    template <int N> 
    double segment() 
     { 
      return 42; 
     } 
}; 

template <int M> 
double func() 
{ 
    a_type<double, M> a; 
    return a.segment<1>(); 
} 

int main(int argc, char *argv[]) 
{ 
    std::cout << func<10>() << std::endl; 
    return 0; 
} 

Các thông báo lỗi từ GCC lần đọc:

g++ main.cpp -o main 
main.cpp: In function 'double func()': 
main.cpp:18:26: error: expected primary-expression before ')' token 
     return a.segment<1>(); 
         ^
main.cpp: In instantiation of 'double func() [with int M = 10]': 
main.cpp:23:28: required from here 
main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<' 
     return a.segment<1>(); 
       ^

Clang cũng nói điều gì đó tương tự:

clang++ main.cpp -o main 
main.cpp:18:26: error: expected expression 
    return a.segment<1>(); 
         ^

Vì vậy, dựa trên thông báo lỗi của GCC, 'a.segment' là một cuộc gọi hàm thành viên thiếu các dấu ngoặc đơn, rõ ràng là bị từ chối. Nhưng điều đó không có ý nghĩa gì cả, vì tôi không thấy lý do nào để đối xử với biểu hiện đó như thế. Hơn nữa, nếu tôi thay đổi M để bất kỳ số lượng không thể thiếu trên dòng 17, như vậy:

#include <iostream> 

template <typename T, int R> 
class a_type 
{ 
public: 
    template <int N> 
    double segment() 
     { 
      return 42; 
     } 
}; 

template <int M> 
double func() 
{ 
    a_type<double, 58> a; 
    return a.segment<1>(); 
} 

int main(int argc, char *argv[]) 
{ 
    std::cout << func<10>() << std::endl; 
    return 0; 
} 

sau đó mã biên dịch và tạo ra kết quả mong đợi.

Tôi sẽ rất hạnh phúc nếu ai đó có thể khai sáng cho tôi và cho tôi thấy những gì tôi đang thiếu ở đây.

Trả lời

4

Trình biên dịch không biết rằng a.segment là mẫu (có thể phụ thuộc vào giá trị M). Vì vậy, bạn phải nói điều đó:

return a.template segment<1>(); 

Trong ví dụ thứ hai của bạn, nó biết mọi thứ về loại a và do đó không có vấn đề gì.

+0

Rất cám ơn cho câu trả lời của bạn! Tôi đã hoàn toàn quên mất việc sử dụng từ khóa mẫu đó. Đoán C++ của tôi đã nhận được một chút gỉ ;-) – Tachikoma

1

Trình biên dịch sẽ cho bạn biết rằng nó có vấn đề với

a_type<double, M> a; 
return a.segment<1>(); 

bởi vì nó không thể nói những gì thành viên a có thể có, vì nó là một mẫu (mà có thể được chuyên cho một số giá trị của M).

main.cpp:18:22: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<' return a.segment<1>(); ^

Nếu segment là một mẫu, nó sẽ được xử lý như segment<1>. Nếu segment là biến thành viên của a, nó phải được biên dịch là a.segment < 1. Làm thế nào là trình biên dịch để biết?

Bạn có thể khắc phục điều này bằng cách sử dụng

return a.template segment<1>(); 
Các vấn đề liên quan