В чем разница между is_convertible is_assignable

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

Ответ 1

Одно отличие состоит в том, что аргументы противоположны.

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, что дает мне неправильный результат.

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

Ответ 2

Кажется, что ошибка в gcc, is_convertible в этом контексте означает, что:

int& foo()
{
    return 3; //invalid
}

С другой стороны, is_assignable в этом контексте означает, что:

void foo(int& x, int y)
{
    y = x; // valid
}