Неверное разрешение перегрузки для функций с двумя аргументами
Давайте возьмем следующий пример программы:
#include <cmath>
namespace half_float
{
template<typename T> struct half_expr {};
struct half : half_expr<half>
{
operator float() const;
};
template<typename T> half sin(const half_expr<T>&);
template<typename T> half atan2(const half_expr<T>&, const half_expr<T>&);
}
using namespace std;
using half_float::half;
int main()
{
half a, b;
half s = sin(a);
half t = atan2(a, b);
}
ВVS 2010 это прекрасно компилируется (пока игнорируем очевидные ошибки компоновщика). Но вVS 2012 это дает мне:
ошибка C2440: «преобразование»: невозможно преобразовать из «float» в «half_float :: half»
Похоже, что разрешение перегрузки не выбирает версию из пространства имен.half_float
(что ADL должен выполнить), но один изstd
используя неявное преобразование вfloat
, Но странно то, что это происходит только дляatan2
звоните, а неsin
вызов.
В более крупном проекте, где эта ошибка фактически впервые возникла у меня, она также возникает для других функций с двумя аргументами (или, скорее всего, с 2half
аргументы), какfmod
, но не для любой функции с 1 аргументом. Аналогично в более крупном проекте он также отлично работает дляgcc 4.6 / 4.7 а такжелязг 3.1 без ошибок, хотя я не тестировал эту версию SSCCE там явно.
Итак, мой вопрос, это ошибочное поведение наVS 2012сторона (учитывая, что это происходит только для2012 и только для функции с двумя аргументами), или я наблюдал за некоторыми тонкостями в правилах разрешения перегрузки (которые, я думаю, могут быть немного хитрыми)?
РЕДАКТИРОВАТЬ: Также бывает, если я напрямуюusing namespace half_float
или поместите все это в глобальное пространство имен напрямую. Точно так же это происходит, если я неusing namespace std
, но это скорее VS-реализация, помещающая математические функции в глобальное пространство имен.
РЕДАКТИРОВАТЬ: Бывает как с оригиналомВК 2012 компилятор, а такжеНоябрь 2012 ОСАГО этого
РЕДАКТИРОВАТЬ: Хотя я не совсем уверен, что это действительно нарушение стандарта в самом строгом смысле, я подалошибка поскольку он основан на выводах из моего ответа, поскольку он по меньшей мере не соответствует определению функций с 1 аргументом и заслуживает дальнейшего изученияВ.С.-Team.