В чем разница между is_convertible и is_assignable?
Почему
в vs2012
is_convertible<int, int&> is false
is_assignable<int, int&> is true
в gcc4.7.2
is_convertible<int, int&> is false
is_assignable<int, int&> is false
В чем разница между is_convertible и is_assignable?
Почему
в vs2012
is_convertible<int, int&> is false
is_assignable<int, int&> is true
в gcc4.7.2
is_convertible<int, int&> is false
is_assignable<int, int&> is false
Одно отличие состоит в том, что аргументы противоположны.
is_convertible<From,To> означает, что выражение типа From может быть преобразовано в тип To. Стандарт определяет это в терминах функции, возвращающей To, содержащей строку return create<From>();, где create<From>() возвращает ссылку на From. Таким образом, is_convertible<int,int&> является ложным, так как вы не можете привязать значение rvalue int к заданию без константы l int&.
is_assignable<T,U> означает, что выражение rvalue типа U может быть присвоено выражению типа T; т.е. что t = u; является корректным. Выражение, которое должно быть назначено, указывается как вызов функции, возвращающий ссылку lvalue, если T является ссылкой на lvalue и в противном случае ссылкой rvalue. Это означает, что is_assignable<T,U> может быть истинным только в том случае, если T является неконстантным ссылочным типом lvalue; следовательно, является ложным для <int,int&>.
Я бы предположил, что VS2012 либо позволяет присваивать значениям x, либо использует нестандартную проверку для is_assignable, что дает мне неправильный результат.
Обратите внимание, что в целом конвертируемый не подразумевает назначение, поскольку не может быть доступного оператора присваивания; и присваиваемый не подразумевает конвертируемый, поскольку может быть оператор присваивания, но нет доступного конструктора преобразования или оператора.
Кажется, что ошибка в gcc, is_convertible в этом контексте означает, что:
int& foo()
{
return 3; //invalid
}
С другой стороны, is_assignable в этом контексте означает, что:
void foo(int& x, int y)
{
y = x; // valid
}