I'm trying to implement managed->native converter in c++/cli. There are about 20 types to convert so I'm trying to use templates for this. The problem is that I should handle values types and reference types differently.
Here is what I'm trying to implement (this code is OK. At least it compiles):
#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;
}
But when I'm trying to specialize some template, for example like this:
template<>
static array<ref_t_constraint(Guid)^>^ convert(const std::vector<char>& native)
{
return gcnew array<Guid^>(1);
}
I got an error "error C2912: explicit specialization 'cli::array ^Baz::convert(const std::vector> &)' is not a specialization of a function template".
Constraints through unused function parameter give me another error - template function specialisations cannot have default parameters. Constraints through additional template arguments don't work. I guess because of the SFINAE implementation in VC++120.
Is it possible to implement such solution? Maybe I'm doing something wrong? I'm using VC++120.