2016-11-15 5 views
4

рассмотрит следующий код:шаблон специализации для внутреннего класса

struct X 
{ 
    template <typename T> 
    class Y 
    {}; 
}; 
template<> 
class X::Y<double>{ 
}; 

здесь мы специализирующиеся класс Y для типа двойными и код работает отлично. проблема заключается в том, что если я изменить код для этого:

template<typename A> 
struct X 
{ 
    template <typename T> 
    class Y 
    {}; 
}; 
template<typename A> 
class X<A>::Y<double>{ 
}; 

компилятор выдаст сообщение об ошибке:

'X::Y': explicit specialization is using partial specialization syntax, use template <> instead!

дозу любой знает, как я могу специализироваться класса Y в этом случае?

+0

ли делать то, что сообщение об ошибке говорит, что не поможет? Используйте 'template <>' вместо 'template ' по вложенной специализации шаблона. –

+0

это не работает! Я тоже устал от этого: template <> класс X :: Y { }; – MEMS

ответ

2

Простой ответ - вы не можете полностью специализировать шаблонный внутренний класс шаблонного внешнего класса. Но если вы действительно хотите, чтобы добиться подобного эффекта можно попробовать частичную специализацию с фиктивным дефолтом параметром шаблона:

#include <iostream> 

template<typename A> 
struct X 
{ 
    template <typename T, T* =nullptr> 
    class Y{}; 
}; 

template<typename A> 
template<double *Ptr> 
class X<A>::Y<double, Ptr> { 
public: 
    static constexpr int value = 1; 
}; 

int main() { 
    std::cout << X<int>::Y<double>::value << std::endl; 
} 

[live demo]

+1

книга: Расширенное метапрограммирование в классических C++, на странице 33 говорит: Шаблон специализации действительны только на уровне пространства имен: структуры X { шаблон класса Y {}; шаблон <> // незаконный, но обычно допускаемый компиляторами класс Y {}; }; template <> // legal класс X :: Y { }; , так что вы сделали, возможно, работа, но не всегда! – MEMS

+0

@MEMS Возможно, вы являетесь автором. Изучив примеры стандартов, я понял, что мог бы на самом деле переучитывать '[temp.class.spec]/5'. Обновление кода –

+1

@MEMS в соответствии с активными проблемами на языке C++ Standard Core '727. В классе явных специализаций встроенная частичная специализация класса-члена хорошо сформирована ... так что мой предыдущий код действительно действительно. Пожалуйста, найдите [ссылку] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#727) –

3

Вы не можете специализировать внутренний класс шаблонов, не явно специализируя внешний. See this question for more details and a quote from the standard.

Обход: создать внешний класс, который принимает как T и A в подробном пространстве имен, и псевдоним он внутри X:

namespace impl 
{ 
    template <typename A, typename T> 
    struct Y { }; 
} 

template<typename A> 
struct X 
{ 
    template <typename T> 
    using Y = impl::Y<A, T>; 
}; 

Если вы хорошо с явно специализирующимися как внутренними и вы можете использовать следующий синтаксис:

template <> 
template <> 
class X<int>::Y<double> 
{ 
    // ... 
}; 

Example on wandbox

+0

Что делать, если я хочу его специализировать для конкретных X и Y, таких как: template <> класс X :: Y { }; в этом случае тоже жалуется! он говорит: ошибка C2992: 'X :: Y ': неверный или отсутствующий список параметров шаблона – MEMS

+0

@MEMS: вам нужен двойной 'template <>'. [Пример по wandbox] (http://melpon.org/wandbox/permlink/5QsXzayEWYB8Vz1E). –

+0

Обновлен мой ответ. –