Шаблон Аргумент Руководство по выводу для типа аргумента unique_ptr? - PullRequest
0 голосов
/ 04 октября 2018

Можно ли написать руководство по выводам, чтобы экземпляр Simple мог быть объявлен без аргументов шаблона?Я пытался, но не могу получить правильную форму для извлечения std::unique_ptr типа элемента.

//------------------------------------------------------------------------------
template< class T >
class Simple
{
public:
    Simple( std::unique_ptr< T >& u ) :
    u_( u )
    {}
private:
    std::unique_ptr< T >& u_;
};

class MyThing
{};

int main()
{
    std::unique_ptr< MyThing > upSimple;
    Simple( upSimple ); // error C2955: 'Simple': use of class template requires template argument list
}

1 Ответ

0 голосов
/ 04 октября 2018

Можно ли написать руководство по выводу, чтобы экземпляр Simple мог быть объявлен без аргументов шаблона?Я пытался, но не могу получить правильную форму для извлечения типа элемента std :: unique_ptr.

Проблема в другом.

Неявно сгенерированные направляющие вычитания вполне способны извлечьправильный шаблонный тип параметра для Simple.

Как указывалось Rakete1111, это своего рода проблема "наиболее неприятного анализа".

Запись

Simple( upSimple );

yourНамерение состояло в том, чтобы получить инициализацию неназванного временного объекта типа Simple (Simple<MyThing>, благодаря новым неявно сгенерированным руководствам по выводам C ++ 17), инициализированного с объектом upSimple.

К сожалению, компилятор(visual-c ++, но то же самое с g ++ и clang ++) интерпретировать его как объявление новой переменной (обратите внимание, что круглые скобки, объявляющие переменные C ++, излишни, но совершенно допустимы; с int (i); вы объявляете переменную i типа int) имени upSimple и типа Simple.

Это дает ошибку, потому что

(1) upSimple определено в предыдущей строке, поэтому мы ha a redeclaration upSimple

(2) неявно сгенерированные руководства по выводам не могут без аргумента конструктора вывести аргумент шаблона T для Simple.

Чтобы избежать этогонеоднозначность и получить инициализацию объекта Simple<MyThing>, вы можете сохранить значение в переменной с помощью

auto s = Simple(upSimple);

или также с

Simple s(upSimple);

, чтобы компилятор не мог интерпретироватьстрока как объявление переменной upSimple больше.

Если вы действительно хотите неназванный временный объект, вы можете использовать равномерную инициализацию (вы можете использовать скобки вместо скобок)

//.....V..........V
Simple { upSimple };

, чтоне может быть истолковано как объявление переменной.

И, да: также навязывание использования нового стандарта C ++ 17 (через /std:c++17 или -std=c++17 или что требуется от конкретного компилятора) можетбыть полезным.

...