将 std::unique_ptr 的子类与 std::variant 一起使用
Using subclass of std::unique_ptr with std::variant
我有一个 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>, = 0, = 0, = 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
为什么它(似乎?)没有解构函数也能工作?
因为 Wrapper
继承自 unique_ptr
这个 class 的实例只能被移动。
您已经为 Wrapper 定义了析构函数,因此移动操作(构造函数和赋值运算符)已被删除 - 当编译器生成移动操作时,您可以阅读 here。
你可以:
1) 移除Wrapper的析构函数,然后编译器生成默认的移动操作
或
2) 添加移动操作
Wrapper(T *value): unique_ptr<T>(value) {};
Wrapper(Wrapper&&) = default; // added
~Wrapper() { cout << "deconstructing Wrapper" << endl; };
我有一个 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>, = 0, = 0, = 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
为什么它(似乎?)没有解构函数也能工作?
因为 Wrapper
继承自 unique_ptr
这个 class 的实例只能被移动。
您已经为 Wrapper 定义了析构函数,因此移动操作(构造函数和赋值运算符)已被删除 - 当编译器生成移动操作时,您可以阅读 here。
你可以:
1) 移除Wrapper的析构函数,然后编译器生成默认的移动操作
或
2) 添加移动操作
Wrapper(T *value): unique_ptr<T>(value) {};
Wrapper(Wrapper&&) = default; // added
~Wrapper() { cout << "deconstructing Wrapper" << endl; };