2015-07-22 17 views
8

Tôi gặp sự cố về lỗi thay thế và câu trả lời của một số câu hỏi tương tự không giúp tôi.mẫu ứng cử viên bị bỏ qua: lỗi thay thế (lỗi với clang nhưng không phải g ++)

Đây là mã:

template<int dim, int loop> 
class Reference{ 
public: 
    //... 
    template<int r, int c> using matrix_t = int[r][c]; 
    Reference(const matrix_t<dim, loop> &mat){} 
}; 

template<int dim, int loop> 
class Partition{ 
    // ... 
public: 
    // ... 
    template<int r, int c> using matrix = int[r][c]; 
    template<int r, int c> void readPattern(const matrix<r,c> &pattern) 
    { 
     // ... 
    } 
    // ... 
}; 

Và tôi gọi mẫu chức năng này như sau:

int main() 
{ 
    // ... 
    const int DENOISE_UR[3][4] = {/*...*/}; 
    Partition<1,2> partition; 
    partition.readPattern(DENOISE_UR); 
    // ... 
} 

Sử dụng g ++, nó biên dịch.

Khi sử dụng kêu vang ++ (linux) để biên dịch (clang++ -std=c++11 xxx.cpp), nó dẫn đến các lỗi biên dịch sau:

error: no matching function for call to 'readPattern' 
    note: candidate template ignored: substitution failure[ with r = 3, c = 4 ] 
     template<int r, int c> void readPattern(const matrix<r,c> &pattern) 

Tại sao?

+1

oO nếu bạn loại bỏ các định nghĩa của 'Reference', [nó biên dịch] (http: // melpon.org/wandbox/permlink/xx2K1gu0J4PFutiP) ... – Columbo

+0

@Columbo Đó chính xác là vấn đề. Tôi cần sử dụng lớp 'Tham chiếu' trong lớp' Phân vùng' – Shindou

+1

@Columbo Thay đổi mẫu bí danh đầu tiên thành 'long [r] [c]': http://melpon.org/wandbox/permlink/0DHbcs3C0dm9H3gX ò.Ó – dyp

Trả lời

4

Đó là lỗi trong tiếng lóng; nó sai khi một mẫu bí danh xác định một loại mảng được định nghĩa trong một mẫu lớp. Trong thực tế nó có thể được khai thác để crash the compiler:

template<int I> 
struct S { 
    template<int J> using T = int[J]; 
    using U = T<I>; 
}; 
S<3>::U a; 

Vì trong trường hợp của bạn Reference::matrix_t không phụ thuộc vào các đối số mẫu để Reference, thực hiện giải pháp đơn giản nhất sẽ được di chuyển định nghĩa của matrix_t đến không gian tên Phạm vi:

namespace impl { template<int r, int c> using matrix_t = int[r][c]; } 
// ... 
template<int dim, int loop> 
class Reference { 
    //... 
    template<int r, int c> using matrix_t = impl::matrix_t<r, c>; 

Trong thực tế, bạn thậm chí không cần phải sử dụng impl::matrix_t để workaround lỗi:

namespace magic { template<int r, int c> using unused = int[r][c]; } // Huh? 
// ... 
template<int dim, int loop> 
class Reference { 
    //... 
    template<int r, int c> using matrix_t = int[r][c]; // Look ma, no hands! 

Đây là now fixed (sửa chữa nên có trong phiên bản phát hành kêu vang 3.8.0):

[AST] Perform additional canonicalization for DependentSizedArrayType

We treated DependentSizedArrayTypes with the same element type but differing size expressions as equivalently canonical. This would lead to bizarre behavior during template instantiation.

This fixes PR24212.

+0

Vâng ... Chỉ cần thêm ma thuật 'không gian tên không liên quan' sẽ giải quyết được lỗi ... Tôi xin lỗi tôi không hoàn toàn tốt với tiếng Anh, nhưng những gì hiện 'Nhìn ma, không có nghĩa là gì? – Shindou

+0

@Shindou đoán rất hoang dã của tôi sẽ được rằng clang kết thúc với một tham chiếu lơ lửng đến một mẫu bí danh, và thêm 'không gian tên ma thuật' đảm bảo rằng tham chiếu lơ lửng chỉ đến một cái gì đó. "Nhìn ma, không tay" là một trò đùa - đó là những gì bạn nói khi bạn đang đi xe đạp và lấy tay ra khỏi tay lái. :) – ecatmur

Các vấn đề liên quan