В чем разница между 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
}