Специализация шаблонов с ограничениями в C++

Я пытаюсь реализовать управляемый-> собственный преобразователь в С++/cli. Есть около 20 типов для преобразования, поэтому я пытаюсь использовать для этого шаблоны. Проблема в том, что я должен обрабатывать типы значений и ссылочные типы по-разному.

Вот что я пытаюсь реализовать (этот код в порядке. По крайней мере, он компилируется):

#define val_t_constraint(T) std::enable_if_t<std::is_integral<T>::value || std::is_floating_point<T>::value, T>
#define ref_t_constraint(T) std::enable_if_t<!std::is_integral<T>::value && !std::is_floating_point<T>::value, T>

template<class TElementIn, class TElementOut = TElementIn>
static val_t_constraint(TElementOut) convert(const TElementIn& native)
{
    return (TElementOut)native;
}

template<class TElementIn, class TElementOut = TElementIn>
static ref_t_constraint(TElementOut)^ convert(const TElementIn& native)
{
    return gcnew TElementOut();
}

template<class TElementIn, class TElementOut = TElementIn>
static array<val_t_constraint(TElementOut)>^ convert(const std::vector<TElementIn>& native)
{
    auto arr = gcnew array<TElementOut>(1);
    arr[0] = convert<TElementIn, TElementOut>(native[0]);
    return arr;
}

template<class TElementIn, class TElementOut = TElementIn>
static array<ref_t_constraint(TElementOut)^>^ convert(const std::vector<TElementIn>& native)
{
    auto arr = gcnew array<TElementOut^>(1);
    arr[0] = convert<TElementIn, TElementOut>(native[0]);
    return arr;
}

Но когда я пытаюсь специализировать какой-то шаблон, например, так:

template<>
static array<ref_t_constraint(Guid)^>^ convert(const std::vector<char>& native)
{
    return gcnew array<Guid^>(1);
}

Я получил сообщение об ошибке "ошибка C2912: явная специализация 'cli::array ^Baz::convert(const std::vector> &)' не является специализацией шаблона функции".

Ограничения через неиспользуемый параметр функции дают мне еще одну ошибку - специализации функций шаблона не могут иметь параметры по умолчанию. Ограничения через дополнительные аргументы шаблона не работают. Я думаю, из-за реализации SFINAE в VC++120.

Возможно ли реализовать такое решение? Может я что-то не так делаю? Я использую VС++120.


person Dmitry Katkevich    schedule 05.09.2016    source источник
comment
Вы уверены насчет «ограничения» (а не «ограничения»)? не то чтобы это имело значение, но англоговорящие могут быть сбиты с толку.   -  person Walter    schedule 05.09.2016
comment
Если вы хотите обрабатывать значения и ссылаться по-разному, почему тогда вы используете не соответствующие черты типа, а что-то совершенно не связанное (а именно is_integral и is_floating_point)?   -  person Walter    schedule 05.09.2016
comment
@Walter Когда я увидел разные типы обработки значений и ссылочных типов, я имел в виду, что в c++\CLI, если вы хотите иметь массив встроенного простого типа (например, int, float или bool), вы должны создать его следующим образом: gcnew array‹int› () без '^', поскольку другие типы (ссылочный тип) должны создаваться с использованием синтаксиса array‹Type^› (с '^')   -  person Dmitry Katkevich    schedule 05.09.2016


Ответы (1)


Я неправильно специализировал шаблон. Правильная версия:

template<>
static array<Guid> convert<char, Guid>(const std::vector<char>& native)
{
    auto arr = gcnew array<Guid>(1);
    arr[0] = convert<char, Guid>(native[0]);
    return arr;
}
person Dmitry Katkevich    schedule 05.09.2016