Сбой частичного упорядочения в C ++ с двумя параметрами шаблона - PullRequest
3 голосов
/ 21 июня 2010

Так даны следующие шаблонные функции с частичной специализацией

template<typename T>
void foo(vector<T> &in) {
    cout << "vector" << endl;
}

template<typename T>
void foo(T &in) {
    cout << "scalar" << endl;
}

int main(int arc, char *argv[]) {
    vector<double> a;
    double b;

    foo(a);
    foo(b);
    return 0;
}

У меня нет проблем с компиляцией с g ++ 3.4.6 и получением ожидаемого результата:

vector
scalar

Теперь, если я добавлю второй параметр шаблона:

template<class U, typename T>
void foo2(vector<T> &in) {
    U a;
    cout << "vector" << endl;
}

template<class U, typename T>
void foo2(T &in) {
    U a;
    cout << "scalar" << endl;
}

и назовите его следующим:

int main(int arc, char *argv[]) {
    vector<double> a;
    double b;

    foo2<double>(a);
    foo2<double>(b);
    return 0;
}

Когда я пытаюсь его скомпилировать, GCC 3.4.6 выдает мне неоднозначную ошибку перегрузки.

error: call of overloaded `foo2(std::vector<double, std::allocator<double> >&)' is ambiguous
note: candidates are: void foo2(std::vector<T, std::allocator<_T2> >&) [with U = double, T = double]
note:                 void foo2(T&) [with U = double, T = std::vector<double, std::allocator<double> >]

Я не вижу, как второй параметр шаблона делает перегрузку неоднозначной. Насколько я могу судить, векторная версия должна быть более специализированной. Это просто ошибка в 3.4? Есть ли обходной путь?

Для записи код работает в gcc 4.1 без проблем. К сожалению, некоторые из наших инструментов все еще привязаны к 3.4, поэтому обновление не является решением.

Спасибо.

1 Ответ

2 голосов
/ 21 июня 2010

Похоже, это связано с этим дефектом , который исправлен в последней версии компилятора.Обходные пути должны явно установить все аргументы шаблона или использовать вместо него функтор:

template<typename U>
struct foo2 {
    template<typename T>
    void operator()( std::vector<T> &in ) {
        U a;
        cout << "vector" << endl;
    }
    template<typename T>
    void operator()( T& in ) {
        U a;
        cout << "scalar" << endl;
    }
};

int main(int arc, char *argv[]) {
    vector<double> a;
    double b;

    foo2<double>()(a);
    foo2<double>()(b);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...