Ошибка компиляции при обобщении типов

363
28 декабря 2016, 04:27

Есть некоторая функция, принимающая в качестве аргумента вектор любого типа через шаблон.

template <typename T>
bool my_function( const std::vector< T >& vec, bool pairs ) {
    if( pairs )
        return vec[0].first < vec[1].first;
    else
        return vec[0] < vec[1];
}

У функции есть второй аргумент, показывающий, передается ли функции вектор типа std::pair<>, например, std::pair< int, int >. Пример вызова:

std::vector< std::pair< int, int > > v( std::pair< int, int >(0, 0),
                                        std::pair< int, int >(1, 1) );
bool res = my_function( v, true );

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

std::vector< int > v2( 0, 1 );
bool res2 = my_function( v2, false );
//////
error: request for member ‘first’ in ‘vec.std::vector<_Tp, _Alloc>::operator[]<int, std::allocator<int> >(0)’, which is of non-class type ‘const value_type {aka const int}’

Попытка исправить ситуацию через dynamic_cast не увенчалась успехом:

template <typename T>
bool my_function( const std::vector< T >& vec, bool pairs ) {
    if( pairs ) {
        const std::pair< int, int >* v_0 = dynamic_cast< const std::pair< int, int >* >(&vec[0]);
        const std::pair< int, int >* v_1 = dynamic_cast< const std::pair< int, int >* >(&vec[1]);
        return v_0->first < v_1->first;
    }
    else
        return vec[0] < vec[1];
}
/////
error: cannot dynamic_cast ‘& vec.std::vector<_Tp, _Alloc>::operator[]<int, std::allocator<int> >(0)’ (of type ‘const value_type* {aka const int*}’) to type ‘const struct std::pair<int, int>*’ (source is not a pointer to class)

Как успокоить компилятор? Может быть, есть способ более изящно обобщить типы, без использования второго параметра pairs? Варианты с typeid тоже не работали.

Answer 1

Почему бы вам не воспользоваться специализацией:

template<typename T>
bool my_function( const std::vector<T>& vec)
{
        return vec[0] < vec[1];
}
template<typename T>
bool my_function( const std::vector<pair<T,T>>& vec)
{
        return vec[0].first < vec[1].first;
}

Можно и простой перегрузкой, кстати...

READ ALSO
Вывод на экран и в файл

Вывод на экран и в файл

Нужно вывести одно и то же на экран и в файл, например:

359
Решить задачу по программирыванию С++ [требует правки]

Решить задачу по программирыванию С++ [требует правки]

Составить функцию, позволяющую определить позицию первого вхождения в заданный строку некоторого символа с другой заданной строкиРезультатом...

385
резервное копирование данных и баз с сервера на ubuntu 12.04

резервное копирование данных и баз с сервера на ubuntu 12.04

Проект развернуть на сервере уже какое-то время и пришла пора задуматься о бекапирвоании

341