Результатом ?:
является rvalue, новый объект, если один из аргументов является rvalue.Чтобы создать это значение, компилятор должен скопировать любой результат.
if (some_condition)
S().f(); // Compiler knows that it's rvalue
else
my_other_S.f(); // Compiler knows that it's lvalue
Это по той же причине, по которой вы не можете сделать
struct B { private: B(const B&); };
struct C { C(B&); C(const B&); };
int main() {
B b;
C c(some_condition ? b : B());
}
Я изменил свой пример, потому чтостарый был немного отстой.Здесь вы можете ясно увидеть, что нет способа скомпилировать это выражение, потому что компилятор не может знать, какой конструктор вызывать.Конечно, в этом случае компилятор может привести оба аргумента к const B&
, но по какой-то причине, которая не очень актуальна, это не будет.
Редактировать: Нет, нет, потому что естьнет способа скомпилировать это выражение, так как важные данные о нем (rvalue или lvalue) изменяются во время выполнения.Компилятор пытается решить эту проблему для вас путем преобразования в rvalue путем создания копии, но не может, потому что не может копировать, поэтому не может компилироваться.