Я столкнулся с реальным моментом WTF, когда обнаружил, что приведенный ниже код выводит "указатель".
#include <iostream>
#include <utility>
template<typename T>
struct bla
{
static void f(const T*) { std::cout << "pointer\n"; }
static void f(const T&) { std::cout << "reference\n"; }
};
int main()
{
bla<std::pair<int,int>>::f({});
}
Изменение аргумента шаблона std::pair<int,int>
для int
или любого другого примитивного типа дает (по крайней мере для меня) ожидаемую ошибку "неоднозначной перегрузки". Кажется, что встроенные типы являются особенными здесь, потому что любой пользовательский тип (совокупный, нетривиальный, с дефолтным конструктором и т.д.) Все приводит к вызываемой перегрузке указателя. Я считаю, что шаблон не нужен для его воспроизведения, он просто упрощает тестирование разных типов.
Лично я не думаю, что это логично, и я ожидал бы неоднозначную ошибку перегрузки во всех случаях, независимо от аргумента шаблона. GCC и Clang (и я считаю, MSVC) все не согласны со мной, через С++ 11/14/1z. Заметьте, что я полностью осведомлен о плохом API этих двух перегрузок, и я никогда не напишу что-то вроде этого, я обещаю.
Итак, возникает вопрос: что происходит?