Пожалуйста, рассмотрим следующий фрагмент кода:Чрезмерная оператора плюс для набора классов
template<class E>
class vector_expression
{};
template<class Tuple>
class vector
: public vector_expression<vector<Tuple>>
{};
template<class E1, class E2, class BinaryOperation>
class vector_binary_operation
: public vector_expression<vector_binary_operation<E1, E2, BinaryOperation>>
{
public:
vector_binary_operation(E1&& e1, E2&& e2, BinaryOperation op)
: m_e1(e1), m_e2(e2),
m_op(op)
{}
private:
E1 m_e1;
E2 m_e2;
BinaryOperation m_op;
};
template<class E1, class E2>
vector_binary_operation<E1, E2, std::plus<>> operator+(E1&& e1, E2&& e2) {
return{ std::forward<E1>(e1), std::forward<E2>(e2), std::plus<>{} };
}
Код выше гарантирует, что vector_binary_operation
хранит ссылки на именованные объекты и делает копии для временных. Проблема заключается в интерфейсе operator+
, потому что он фактически определяет этот оператор для любого типа. Что мне нужно изменить, если я хочу сохранить функциональность, но только определить оператор для типов, которые являются или производными от vector_expression
?
список инициализаторов в конструкторе должен быть лучше: 'm_e1 (станд :: вперед (e1)), m_e2 (станд :: вперед (е2)), m_op (Std :: ход (оп)) '. В противном случае вы нарушите цепочку безупречной пересылки. –
davidhigh
@ davidhigh Да, вы правы. Я скопировал код из другого вопроса и там параметры 'e1' и' e2' были ссылками на const. Спасибо, что заметили это. – 0xbadf00d
нет, я ошибаюсь. Я был бы прав, если конструктор был шаблоном функции, что-то вроде 'template vector_binary_operation (E1 _ && e1, E2 _ && e2, BinaryOperation op)'. Кстати, это, вероятно, то, что вы намеревались, когда вы использовали '&&'. Для получения дополнительной информации см. [Здесь] (https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers) –
davidhigh