Типовые черты - Явная специализация шаблона.не удается на Xcode - PullRequest
1 голос
/ 10 октября 2011

Я пытаюсь использовать черты типа, как в «Современном C ++ Design», используя шаблон, чтобы определить, имеет ли тип переменный размер или нет.например, строка требует хранения переменного размера, int имеет хранение фиксированного размера.Этот код работает на Microsoft C ++, теперь я портирую на Mac и получаю ошибку:

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

Что правильноспособ специализировать это?

template <typename T>
class MyTypeTraits
{
    template<class U> struct VariableLengthStorageTraits
    {
        enum { result = false };
    };
    template<> struct VariableLengthStorageTraits<std::wstring>
    {
        enum { result = true };
    };

public:
    enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
};

Ответы [ 3 ]

4 голосов
/ 10 октября 2011

Стандарт 2003 C ++ допускает только специализацию шаблона члена вне определения класса. Кроме того, специализация вне определения должна быть явной полной специализацией включающего шаблона. Microsoft C ++ является нестандартным в этом отношении. Исправление простое, просто переместите внутренний шаблон из вмещающего шаблона, поскольку внутренний шаблон не нуждается в аргументах шаблона вмещающего класса:

template<class U> struct VariableLengthStorageTraits
{
    enum { result = false };
};

template<>
struct VariableLengthStorageTraits<std::wstring>
{
    enum { result = true };
};

template <typename T>
struct MyTypeTraits
{
    enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
};
4 голосов
/ 10 октября 2011

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

#include <type_traits>

template <typename> struct has_variable_length;  // intentionally undefined!
template <> struct has_variable_length<std::wstring> : std::true_type  { };
template <> struct has_variable_length<int>          : std::false_type { };
// ...

template <typename T> struct MyTraits
{
  static const bool variable_length = has_variable_length<T>::value;
  // ...
};

Вы можете заключить отдельные классы черт в пространство имен detail, если хотите.*

0 голосов
/ 25 июня 2012

Переместите специализацию функции за пределы класса и в файл .cpp, он не работает с заголовками.

...