2015-10-13 31 views
12

Một lớp:lớp Nested mẫu chuyên môn

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    Nested<T> n; 
}; 

Và tôi muốn chuyên Nested. Dưới đây là những gì tôi đã cố gắng:

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    template <> 
    class Nested<int>{}; // by my logic this should work by I have a compilation error "explicit specialization in non-namespace scope 'class A<C, T>'" 

    Nested<T> n; 
}; 

nỗ lực tiếp theo của tôi:

template<typename C, typename T> 
class A 
{ 
    template <typename U> 
    class Nested{}; 

    Nested<T> n; 
}; 

template<> 
A<>::Nested<int>{}; // What is the correct syntax to do it here? Now I have an error "wrong number of template arguments (0, should be 2)" 

đây trên stackoverflow Tôi tìm thấy một giải pháp:

template<typename C, typename T> 
class A 
{ 
    template <typename U, bool Dummy = true> 
    class Nested{}; // why need of this Dummy?? 

    template <bool Dummy> 
    class Nested<int, Dummy>{}; // why need to provide an argument?? 

    Nested<T> n; 
}; 

Nó hoàn toàn hoạt động, nhưng tôi không thể hiểu làm thế nào. Tại sao lại cung cấp một đối số mẫu giả? Tại sao tôi không thể sử dụng chuyên môn thô template<> class Nested<int, true>{} hoặc template<> class Nested<int>{}?

Trả lời

12

Nó cấm để tạo chuyên môn hóa rõ ràng trong đẳng cấp phạm vi:

Một chuyên môn hóa rõ ràng phải được khai báo trong một không gian tên kèm theo mẫu chuyên ngành.

Nhưng nó không cấm để tạo chuyên môn hóa từng phần:

Một lớp mẫu chuyên môn hóa một phần có thể được khai báo hoặc redeclared trong bất kỳ phạm vi không gian tên trong đó định nghĩa của nó có thể được định nghĩa (14.5.1 và 14,5 .2).

này

template <bool Dummy> 
class Nested<int, Dummy>{}; // why need to provide an argument?? 

là chuyên môn hóa một phần và nó cho phép tạo chuyên môn như vậy trong đẳng cấp phạm vi. Bạn cũng không thể hoàn toàn chuyên lớp lồng nhau, trong lớp ngoài không chuyên biệt. Bạn có thể làm điều này:

template<> 
template<> 
class A<int, double>::Nested<int> 
{ 
}; 

nhưng bạn không thể làm

template<typename C, typename T> 
template<> 
class A<C, T>::Nested<int> 
{ 
}; 
1

tôi quản lý để có được điều này để làm việc, bằng cách định nghĩa tất cả các nội dung của mẫu chuyên lớp trong lớp ngoài. Vì vậy, tất cả các hàm được định nghĩa hoàn toàn với định nghĩa lớp. Không có định nghĩa chức năng bên ngoài, vì điều đó dường như không tuân thủ. I E.

template <typename T, size_t N> 
class A 
{ 
private: 
    template <size_t M> 
    class B 
    { 
     ... 
    }; 

    template <> 
    class B<2> 
    { 
     ... 
    }; 
    ... etc 
}; 

Nó hoạt động ít nhất là MS2015. Mã đang chạy tốt.

+1

Có, nhưng nó không chạy trên gcc và tiếng lóng. Loos như Microsoft không theo tiêu chuẩn. Hoặc có thể có một trình chuyển đổi trình biên dịch. – nikitablack

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