2014-10-12 2 views
1

Пусть будет класс TArray, который имеет оператор []. Возвращаемый тип Tarray[index] известен, назовем его TResult, но тип index сам, TIndex, я хочу выяснить. С этой целью я определил следующий шаблон: .Ошибка замены шаблона функции в Visual Studio 2013?

template<class TArray, class TResult> 
struct ArrayIndexType 
{ 
    template<class TIndex> 
    using OperatorFunc = TResult(TArray::*)(TIndex); 

    template<class TIndex> 
    static TIndex test(OperatorFunc<TIndex>); 

    using type = decltype(test(&TArray::operator[])); 
}; 

и это на самом деле работает для станд :: вектор:

cout << typeid(ArrayIndexType<vector<double>, /*TResult=*/double&>::type).name(); 
// output: unsigned int. 

но когда я делаю то же самое для простейшего наследования:

class DoubleVec: public vector<double> 
{}; 
cout << typeid(ArrayIndexType<DoubleVec, /*TResult=*/double&>::type).name(); 

Я получаю ошибку компиляции C2664: «TIndex ArrayIndexType :: test (TResult (__thiscall DoubleVec :: *) (TIndex)) ': не может преобразовать аргумент 1 из' перегруженной функции 'в' double & (__thiscall DoubleVec :: *) (unsigned int) '

который в основном означает, что компилятор не может выбрать между 2 перегрузками для оператора [], определенного в векторе: double& vector::operator[](size_t) и const double& vector::operator[](size_t). Является ли это ошибкой в ​​MSVS 2013 или я что-то не так?

Возможно, есть лучший способ достичь цели, то есть получить тип аргумента оператора []? Спасибо за ответы.

ответ

1

Это не ошибка. Тип &DoubleVec::operator[] по-прежнему «указатель на функцию-член std::vector<double>», и компилятор не может вывести из него «указатель на функцию-член DoubleVec».

Это все в значительной степени бессмысленно в любом случае для стандартных контейнеров:

template<class T> 
using ArrayIndexType = typename T::size_type; 

Альтернативно, шаблон OperatorFunc от типа класса, а также:

template<class TArray, class TResult> 
struct ArrayIndexType 
{ 
    template<class T, class TIndex> 
    using OperatorFunc = TResult(T::*)(TIndex); 

    template<class T, class TIndex> 
    static TIndex test(OperatorFunc<T, TIndex>); 

    using type = decltype(test(&TArray::operator[])); 
}; 
+0

Brilliant! Ваше второе предложение работает и действительно то, что мне нужно, потому что этот макрос будет использоваться не только для std :: vector, на самом деле. –

Смежные вопросы