我有以下代码
class MyValue
{
std::any value;
MyValue(std::any value)
: value(value)
{
}
public:
using ErrorType = std::string;
using MaybeMy = std::variant<ErrorType, MyValue>;
static MaybeMy safeWrap(std::any const &obj) noexcept
{
if (std::any_cast<int>(&obj) != nullptr)
return MyValue(obj);
else
return ErrorType("There is some alien type");
}
operator std::string() const
{
return std::to_string(std::any_cast<int>(value));
}
MyValue(MyValue &&) = default;
};
int main()
{
auto printer = [](auto &&v) { std::cout << std::string(v) << std::endl; };
MyValue::MaybeMy as[] = {MyValue::safeWrap(10), MyValue::safeWrap("10")};
for (auto &&v : as)
std::visit(printer, v);
}
但是我收到与std :: variant相关的错误-MyValue不可构造。 我不明白原因。
为什么MyValue
不可构造?为什么执行代码有一些限制?
编译器的输出:
[build] In file included from /usr/include/c++/9/variant:36,
[build] from /home/created/Documents/Cpp/gstream_test/main.cpp:8:
[build] /usr/include/c++/9/type_traits: In instantiation of ‘struct std::__and_<std::is_copy_constructible<MyValue>, std::is_constructible<MyValue, const MyValue&> >’:
[build] /usr/include/c++/9/any:181:58: required by substitution of ‘template<class _ValueType, class _Tp, class _Mgr, typename std::enable_if<std::__and_<std::is_copy_constructible<_Tp>, std::is_constructible<_Tp, _ValueType&&> >::value, bool>::type <anonymous>, typename std::enable_if<(! std::__is_in_place_type<_Tp>::value), bool>::type <anonymous> > std::any::any(_ValueType&&) [with _ValueType = const MyValue&; _Tp = MyValue; _Mgr = std::any::_Manager_external<MyValue>; typename std::enable_if<std::__and_<std::is_copy_constructible<_Tp>, std::is_constructible<_Tp, _ValueType&&> >::value, bool>::type <anonymous> = <missing>; typename std::enable_if<(! std::__is_in_place_type<_Tp>::value), bool>::type <anonymous> = <missing>]’
[build] /usr/include/c++/9/type_traits:883:12: required from ‘struct std::is_constructible<MyValue, const MyValue&>’
[build] /usr/include/c++/9/type_traits:901:12: required from ‘struct std::__is_copy_constructible_impl<MyValue, true>’
[build] /usr/include/c++/9/type_traits:907:12: required from ‘struct std::is_copy_constructible<MyValue>’
[build] /usr/include/c++/9/type_traits:2925:25: required from ‘constexpr const bool std::is_copy_constructible_v<MyValue>’
[build] /usr/include/c++/9/variant:275:5: required from ‘constexpr const bool std::__detail::__variant::_Traits<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>::_S_copy_ctor’
[build] /usr/include/c++/9/variant:1220:11: required from ‘class std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>’
[build] /home/created/Documents/Cpp/gstream_test/main.cpp:26:5: required from here
[build] /usr/include/c++/9/type_traits:131:12: error: incomplete type ‘std::is_copy_constructible<MyValue>’ used in nested name specifier
[build] 131 | struct __and_<_B1, _B2>
[build] | ^~~~~~~~~~~~~~~~
[build] /usr/include/c++/9/type_traits: In instantiation of ‘struct std::__and_<std::is_copy_constructible<MyValue>, std::__not_<std::is_constructible<MyValue, const MyValue&> >, std::__not_<std::__is_in_place_type<MyValue> > >’:
[build] /usr/include/c++/9/type_traits:150:27: required from ‘constexpr const bool std::__and_v<std::is_copy_constructible<MyValue>, std::__not_<std::is_constructible<MyValue, const MyValue&> >, std::__not_<std::__is_in_place_type<MyValue> > >’
[build] /usr/include/c++/9/any:192:27: required by substitution of ‘template<class _ValueType, class _Tp, class _Mgr, typename std::enable_if<__and_v<std::is_copy_constructible<_Tp>, std::__not_<std::is_constructible<_Tp, _ValueType&&> >, std::__not_<std::__is_in_place_type<_Tp> > >, bool>::type <anonymous> > std::any::any(_ValueType&&) [with _ValueType = const MyValue&; _Tp = MyValue; _Mgr = std::any::_Manager_external<MyValue>; typename std::enable_if<__and_v<std::is_copy_constructible<_Tp>, std::__not_<std::is_constructible<_Tp, _ValueType&&> >, std::__not_<std::__is_in_place_type<_Tp> > >, bool>::type <anonymous> = <missing>]’
[build] /usr/include/c++/9/type_traits:883:12: required from ‘struct std::is_constructible<MyValue, const MyValue&>’
[build] /usr/include/c++/9/type_traits:901:12: required from ‘struct std::__is_copy_constructible_impl<MyValue, true>’
[build] /usr/include/c++/9/type_traits:907:12: required from ‘struct std::is_copy_constructible<MyValue>’
[build] /usr/include/c++/9/type_traits:2925:25: required from ‘constexpr const bool std::is_copy_constructible_v<MyValue>’
[build] /usr/include/c++/9/variant:275:5: required from ‘constexpr const bool std::__detail::__variant::_Traits<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>::_S_copy_ctor’
[build] /usr/include/c++/9/variant:1220:11: required from ‘class std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>’
[build] /home/created/Documents/Cpp/gstream_test/main.cpp:26:5: required from here
[build] /usr/include/c++/9/type_traits:136:12: error: incomplete type ‘std::is_copy_constructible<MyValue>’ used in nested name specifier
[build] 136 | struct __and_<_B1, _B2, _B3, _Bn...>
[build] | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[build] /usr/include/c++/9/type_traits: In instantiation of ‘constexpr const bool std::__and_v<std::is_copy_constructible<MyValue>, std::__not_<std::is_constructible<MyValue, const MyValue&> >, std::__not_<std::__is_in_place_type<MyValue> > >’:
[build] /usr/include/c++/9/any:192:27: required by substitution of ‘template<class _ValueType, class _Tp, class _Mgr, typename std::enable_if<__and_v<std::is_copy_constructible<_Tp>, std::__not_<std::is_constructible<_Tp, _ValueType&&> >, std::__not_<std::__is_in_place_type<_Tp> > >, bool>::type <anonymous> > std::any::any(_ValueType&&) [with _ValueType = const MyValue&; _Tp = MyValue; _Mgr = std::any::_Manager_external<MyValue>; typename std::enable_if<__and_v<std::is_copy_constructible<_Tp>, std::__not_<std::is_constructible<_Tp, _ValueType&&> >, std::__not_<std::__is_in_place_type<_Tp> > >, bool>::type <anonymous> = <missing>]’
[build] /usr/include/c++/9/type_traits:883:12: required from ‘struct std::is_constructible<MyValue, const MyValue&>’
[build] /usr/include/c++/9/type_traits:901:12: required from ‘struct std::__is_copy_constructible_impl<MyValue, true>’
[build] /usr/include/c++/9/type_traits:907:12: required from ‘struct std::is_copy_constructible<MyValue>’
[build] /usr/include/c++/9/type_traits:2925:25: required from ‘constexpr const bool std::is_copy_constructible_v<MyValue>’
[build] /usr/include/c++/9/variant:275:5: required from ‘constexpr const bool std::__detail::__variant::_Traits<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>::_S_copy_ctor’
[build] /usr/include/c++/9/variant:1220:11: required from ‘class std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, MyValue>’
[build] /home/created/Documents/Cpp/gstream_test/main.cpp:26:5: required from here
[build] /usr/include/c++/9/type_traits:150:27: error: ‘value’ is not a member of ‘std::__and_<std::is_copy_constructible<MyValue>, std::__not_<std::is_constructible<MyValue, const MyValue&> >, std::__not_<std::__is_in_place_type<MyValue> > >’
[build] 150 | inline constexpr bool __and_v = __and_<_Bn...>::value;
[build] | ^~~~~~~
我正在使用gcc 9.3
答案 0 :(得分:3)
这是一个gcc错误:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
它已在gcc 8和gcc 10+中修复。
当您的构造函数使用std::any
时,就会发生错误,该构造函数会尽早实例化某些类型特征并破坏内容,并在您尝试移动类型时产生硬错误(因为它也考虑了隐式转换)到std::any
)
一种解决方法是,不要通过添加虚拟参数使构造函数采用std::any
:
MyValue(int, std::any value)
: value(value)
{
}
// ...
return MyValue(0, obj);
或改为使用std::experimental::any
/ std::experimental::fundamentals_v1::any
答案 1 :(得分:-1)
班级成员的默认可访问性是私有的。由于您的构造函数位于public:
声明之前,因此没有人可以构造此类的任何对象。