скажем, у меня есть следующий код:
class Element;
typedef shared_ptr<Element> ElementPtr;
class Element
{
public:
void add_child(const ElementPtr& elem);
private:
vector<ElementPtr> children;
}
inline void Element::add_child(const ElementPtr& elem)
{
children.push_back(elem);
};
И я хочу обновить add_child
, чтобы использовать идеальную переадресацию. Я попытался изменить определение функции (и объявление), поэтому используйте следующую логику:
void Element::add_child(ElementPtr&& elem)
{
children.push_back(forward<ElementPtr>(elem));
}
Но это дает сбой для любого вызова, в котором аргумент elem
является lvalue. Поэтому я подумал, что попробую с шаблонами, и придумал следующее:
template <ElementPtr elem>
void Element::add_child(ElementPtr&& elem)
{
children.push_back(forward<ElementPtr>(elem));
}
... Но это не компилируется. Поэтому я изменил его на это:
template <class T>
void Element::add_child(T&& elem)
{
children.push_back(forward<T>(elem));
}
... Который компилируется и работает, но кажется уродливым и неправильным; add_child
будет принимать только аргументы типа ElementPtr
, поэтому не должно ли это отражать его объявление функции?
Есть ли способ реализовать идеальную пересылку для функции, синтаксически демонстрируя, что она принимает только один тип переменной? В основном мне нужна функция, которая автоматически различает версии lvalue и rvalue для определенного типа параметра.