Использование подкласса std :: unique_ptr с std :: option - PullRequest
0 голосов
/ 21 марта 2019

У меня есть подкласс std::unique_ptr, и я пытаюсь использовать его с std::variant.У меня есть следующая настройка

// main.cc
#include <iostream>
#include <variant>

using namespace std;

class Content {
  public:
    Content() = default;
    ~Content() { cout << "deconstructing Content" << endl; };

    int value = 10;
};

template<typename T>
class Wrapper : public unique_ptr<T> {
  public:
    Wrapper(T *value): unique_ptr<T>(value) {};
    ~Wrapper() { cout << "deconstructing Wrapper" << endl; };
};

static variant<Wrapper<Content>, int> do_sth(bool flag) {
  if (flag) return Wrapper(new Content());
  return 1;
}

int main(int argc, const char *argv[]) {
  auto result = do_sth(true);
  if (auto wrapper = get_if<Wrapper<Content>>(&result)) {
    cout << wrapper->get()->value << endl;
  } else {
    cout << *get_if<int>(&result) << endl;
  }

  return 0;
}

, скомпилированная на macOS 10.14 с Xcode 10.1 с использованием

$ #c++ --version -> Apple LLVM version 10.0.0 (clang-1000.11.45.5)
$ c++ -std=gnu++17 main.cc

Жалобы компилятора на следующие

main.cc:25:12: error: no viable conversion from returned value of type 'Wrapper<Content>' to function return type 'variant<Wrapper<Content>, int>'
    return Wrapper(new Content());
           ^~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/variant:1142:3: note: candidate constructor not viable: no
      known conversion from 'Wrapper<Content>' to 'const std::__1::variant<Wrapper<Content>, int> &' for 1st argument
  variant(const variant&) = default;
  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/variant:1155:13: note: candidate template ignored:
      substitution failure [with _Arg = Wrapper<Content>, $1 = 0, $2 = 0, $3 = 0]: no type named 'type' in
      'std::__1::result_of<std::__1::__variant_detail::__overload<Wrapper<Content>, int> (Wrapper<Content> &&)>'
  constexpr variant(_Arg&& __arg) noexcept(
            ^
1 error generated.

У меня два вопроса: Во-первых, что я делаю не так?Во-вторых, когда я удаляю деконструктор Wrapper, то есть

template<typename T>
class Wrapper : public unique_ptr<T> {
  public:
    Wrapper(T *value): unique_ptr<T>(value) {};
};

, он компилируется и запускается со следующим выводом

10
deconstructing Content

Почему это (кажется?) Работаетбез деконструктора?

1 Ответ

3 голосов
/ 21 марта 2019

Поскольку Wrapper наследуется от unique_ptr, экземпляр этого класса можно перемещать только.

Вы определили деструктор для Wrapper, поэтому операции перемещения (конструктор и оператор присваивания) удалены - вы можете прочитать здесь , когда операции перемещения генерируются компилятором.

Вы могли бы:

1) удалить деструктор Wrapper, затем компилятор генерирует операции перемещения по умолчанию

или

2) добавить операции перемещения

Wrapper(T *value): unique_ptr<T>(value) {};
Wrapper(Wrapper&&) = default; // added
~Wrapper() { cout << "deconstructing Wrapper" << endl; };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...