почему ptr_fun находит это неоднозначным, даже если заданы параметры шаблона? - PullRequest
8 голосов
/ 12 июля 2011

Итак, вот базовый код, иллюстрирующий мой вопрос:

#include <functional>

int func(int x) {
    return x;
}

int func(int x, int y) {
    return x + y;
}

int main() {
    std::ptr_fun<int, int>(func);
}

У нас есть 2 перегрузки для функции с различным количеством параметров. Затем я пытаюсь превратить версию с одним параметром в функтор. Разумеется, меня встречает следующая ошибка:

test.cc: In function 'int main()':
test.cc:13:29: error: call of overloaded 'ptr_fun()' is ambiguous
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_function.h:437:5: note: candidates are: std::pointer_to_unary_function std::ptr_fun(_Result (*)(_Arg)) [with _Arg = int, _Result = int]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4/bits/stl_function.h:463:5: note:                 std::pointer_to_binary_function std::ptr_fun(_Result (*)(_Arg1, _Arg2)) [with _Arg1 = int, _Arg2 = int, _Result = int]

Я знаю, что могу просто разыграть func и покончить с этим , но это заставило меня задуматься почему это неоднозначно ? Ни одна из версий std::ptr_fun не имеет параметров по умолчанию в определениях шаблонов, и я прямо сказал, что двумя параметрами шаблона являются int.

На самом деле, если я просто сделаю то, что, по сути, делает компилятор во время создания шаблона, вот так:

#include <functional>

int func(int x) {
    return x;
}

int func(int x, int y) {
    return x + y;
}

std::pointer_to_unary_function<int,int> my_ptr_fun (int (*f)(int)) {
  return std::pointer_to_unary_function<int,int>(f);
}

int main() {
    my_ptr_fun(func);
}    

Он компилируется просто отлично, двусмысленность исчезла! Кто-нибудь знает, почему это так?

1 Ответ

4 голосов
/ 12 июля 2011

Это потому, что когда вы вызываете шаблонную функцию, вам не нужно указывать какие-либо параметры шаблона, которые могут быть выведены по типу аргументов функции.В результате при вызове std::ptr_fun<int, int> фактически не указывается, какая из std::ptr_fun перегрузок вы вызываете, и он полагается на функцию, которую вы передаете в качестве аргумента для разрешения.Поскольку у вашего func есть перегрузки, которые подходят для обеих std::ptr_fun перегрузок, есть неоднозначность.

Редактировать: Вот пример, чтобы продемонстрировать мою точку зрения - работает на Ideone , он показывает обавызовы функций возвращают один и тот же тип.

#include <functional>
#include <iostream>
#include <typeinfo>

double func(int x) 
{
    return x;
}

int main() 
{
    std::cout << typeid(std::ptr_fun<int>(func)).name() << std::endl;
    std::cout << typeid(std::ptr_fun<int, double>(func)).name() << std::endl;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...