Более конкретная перегрузка не называется

Учитывая следующие две функции, я ожидал бы, что первая перегрузка будет вызвана, если я передам ей std::pair<const char*, std::size_t>, поскольку она более специфична, чем общий T.

void foo(const std::pair<const char*, std::size_t>& p)
{
    std::cout << "pair" << std::endl;
}

template <class T>
void foo(const T& v)
{
    std::cout << "generic" << std::endl;
}

int main()
{
    const char* s = "abc";
    foo(std::make_pair(s, std::size_t(3)));
}

Однако эта программа выводит:

generic

Почему вторая перегрузка называется вместо перегрузки, которая явно принимает pair?

Является ли это проблемой компилятора? На данный момент я использую довольно старый компилятор (GCC 4.1.2).

Хм... возможно, это проблема компилятора:

http://ideone.com/97XwwZ

Ответы

Ответ 1

Ваш компилятор, безусловно, ошибочен. Какая ошибка, это будет только предположение, но вы правы, что этот код должен давать более конкретный результат. Образец не является большим или сложным для любого из более тонких правил, которые могут быть причиной.

Ответ 2

Кажется, это просто проблема с компилятором. Я использовал старый компилятор (GCC 4.1.2). Использование менее древнего компилятора, похоже, приводит к правильной перегрузке, которая называется

http://ideone.com/97XwwZ

#include <iostream>
#include <utility>

void foo(const std::pair<const char*, std::size_t>& p)
{
    std::cout << "pair" << std::endl;
}

template <class T>
void foo(const T& v)
{
    std::cout << "generic" << std::endl;
}

int main()
{
    const char* s = "abc";
    foo(std::make_pair(s, std::size_t(3)));
}

Ответ 3

Согласно перегрузке разрешения, он должен предпочесть конкретный вариант в вашем примере.

Я бы сказал, что это ошибка компилятора из-за более старой версии. При компиляции с использованием GCC 4.8.1. Он выводит

pair

по этой ссылке: перегрузка демонстрации разрешения