6

У меня есть следующие две функций шаблона перегрузки:объединяющего сопзЬ T & и T && перегружает

template<typename T> 
optional<T> some(const T& x) 
{ 
    return optional<T>(x); 
} 

template<typename T> 
typename std::enable_if<std::is_rvalue_reference<T&&>::value, optional<T> >::type 
some(T&& x) 
{ 
    return optional<T>(std::move(x)); 
} 

Моей первая попытка унифицировать перегруженные через идеальное экспедирование не удалась:

template<typename T> 
optional<T> some(T&& x) 
{ 
    return optional<T>(std::forward<T>(x)); 
} 

error: forming pointer to reference type 'const std::basic_string<char>&' 

Как сделали мою вторую попытку:

template<typename T> 
optional<typename std::remove_reference<T>::type> some(T&& x) 
{ 
    return optional<typename std::remove_reference<T>::type>(std::forward<T>(x)); 
} 

error: no matching function for call to 
'std::basic_string<char>::basic_string(gpa::optional<const std::basic_string<char> >)' 

Есть ли чистый способ унификации перегрузок, или я должен просто жить с ними?

+1

Вы должны предоставить определение того, что такое 'optional <>'. –

+0

Это в основном игрушечный клон 'boost :: optional'. – fredoverflow

+1

... И все же вопрос стоит, можете ли вы дать определение? У меня такое ощущение, что проблема связана с интерфейсом 'optional' (т. Е. Идеальная пересылка - это решение для' some', вам может потребоваться настроить его, чтобы он соответствовал 'optional') –

ответ

1

В общем, лучший способ сделать это, чтобы принять объект по значению, и пусть вызывающему решить, следует ли скопировать или переместить его:

template<typename T> 
optional<T> some(T x) 
{ 
    return optional<T>(std::move(x)); 
} 

Если вызывающий абонент называет его временным или использует std::move по их значению, затем он перемещается. В противном случае он будет скопирован.

Да, это означает, что вы сделаете еще один шаг (который, если движение совпадает с копированием, означает выполнение двух копий). Если это серьезная проблема с производительностью, вам придется использовать две реализации перегрузки.

4

Я не знаком с вашим optional, но, возможно, вам нужно добавить:

typename remove_const<...>::type 

вокруг remove_reference в двух местах. (потому что ваша первая перегрузка вашего решения с двумя перегрузками, которое, как я полагаю, проходит все ваши тесты, эффективно делает remove_const при объявлении optional<T>).

+0

Не должно быть' remove_cv' только для для большей верности? – pmr

+1

Если это то, что нужно. Текущее решение с 2-мя перегрузками просто отклоняет неактивные значения lvalues. Мне трудно сказать, что нужно, без полного примера кода. –

Смежные вопросы