c++ - 在不同变体模板类的实例之间复制

标签 c++ boost variant

为什么一个变体赋值可以编译而另一个不能?例如,模板实例不共享任何类型,char 可以转换为 intboost::variant 试图做什么,在第一个赋值的情况下它不能做,而在第二个赋值的情况下它可以做?错误如下。

#include <string>

#include "boost/variant.hpp"

int main()
{
  boost::variant<char> v1;
  boost::variant<std::string, int, double> v2;

  v1 = v2; // compile error
  v2 = v1; // compiles fine

  return 0;
}

In file included from /usr/include/boost/variant.hpp:17:0,
                 from v.cpp:3:
/usr/include/boost/variant/variant.hpp: In instantiation of 'int boost::variant<T0, TN>::convert_copy_into::internal_visit(T&, int) const [with T = const std::basic_string<char>; T0_ = char; TN = {}]':
/usr/include/boost/variant/detail/visitation_impl.hpp:113:9:   required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke_impl(int, Visitor&, VoidPtrCV, T*, mpl_::true_) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; typename Visitor::result_type = int; mpl_::true_ = mpl_::bool_<true>]'
/usr/include/boost/variant/detail/visitation_impl.hpp:156:9:   required from 'typename Visitor::result_type boost::detail::variant::visitation_impl_invoke(int, Visitor&, VoidPtrCV, T*, NoBackupFlag, int) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T = std::basic_string<char>; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int]'
/usr/include/boost/variant/detail/visitation_impl.hpp:237:5:   required from 'typename Visitor::result_type boost::detail::variant::visitation_impl(int, int, Visitor&, VoidPtrCV, mpl_::false_, NoBackupFlag, Which*, step0*) [with Which = mpl_::int_<0>; step0 = boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<mpl_::long_<3l>, std::basic_string<char>, boost::mpl::l_item<mpl_::long_<2l>, int, boost::mpl::l_item<mpl_::long_<1l>, double, boost::mpl::l_end> > > >, boost::mpl::l_iter<boost::mpl::l_end> >; Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; NoBackupFlag = boost::variant<std::basic_string<char>, int, double>::has_fallback_type_; typename Visitor::result_type = int; mpl_::false_ = mpl_::bool_<false>]'
/usr/include/boost/variant/variant.hpp:2245:13:   required from 'static typename Visitor::result_type boost::variant<T0, TN>::internal_apply_visitor_impl(int, int, Visitor&, VoidPtrCV) [with Visitor = boost::variant<char>::convert_copy_into; VoidPtrCV = const void*; T0_ = std::basic_string<char>; TN = {int, double}; typename Visitor::result_type = int]'
/usr/include/boost/variant/variant.hpp:2267:13:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/variant/variant.hpp:1581:13:   required from 'void boost::variant<T0, TN>::convert_construct_variant(Variant&) [with Variant = const boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1628:42:   required from 'void boost::variant<T0, TN>::convert_construct(const boost::variant<U0, UN ...>&, long int) [with U0 = std::basic_string<char>; UN = {int, double}; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:1649:38:   required from 'boost::variant<T0, TN>::variant(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2059:29:   required from 'void boost::variant<T0, TN>::assign(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
/usr/include/boost/variant/variant.hpp:2099:19:   required from 'boost::variant<T0, TN>& boost::variant<T0, TN>::operator=(const T&) [with T = boost::variant<std::basic_string<char>, int, double>; T0_ = char; TN = {}]'
v.cpp:10:6:   required from here
/usr/include/boost/variant/variant.hpp:1366:61: error: no matching function for call to 'boost::variant<char>::initializer::initialize(void* const&, const std::basic_string<char>&)'
             return initializer::initialize(storage_, operand);
                                                             ^
/usr/include/boost/variant/variant.hpp:1366:61: note: candidates are:
In file included from /usr/include/boost/variant/variant.hpp:32:0,
                 from /usr/include/boost/variant.hpp:17,
                 from v.cpp:3:
/usr/include/boost/variant/detail/initializer.hpp:104:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param_T = const char&]
             static int initialize(void* dest, param_T operand)
                        ^
/usr/include/boost/variant/detail/initializer.hpp:104:24: note:   no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param_T {aka const char&}'
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >; Iterator = boost::mpl::l_iter<boost::mpl::list1<char> >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = char&&]
             static int initialize(void* dest, param2_T operand)
                        ^
/usr/include/boost/variant/detail/initializer.hpp:115:24: note:   no known conversion for argument 2 from 'const std::basic_string<char>' to 'boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list1<char> > >::initializer_node::param2_T {aka char&&}'
/usr/include/boost/variant/detail/initializer.hpp:149:17: note: static void boost::detail::variant::initializer_root::initialize()
     static void initialize();
                 ^
/usr/include/boost/variant/detail/initializer.hpp:149:17: note:   candidate expects 0 arguments, 2 provided

最佳答案

char 绝对可以存储在 int 中,但反之并不总是正确的。因此,编译失败的编译器在运行时将是不安全的,因此您可能最好不要编译失败。如果必须,将 int 转换为 char

关于c++ - 在不同变体模板类的实例之间复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26778013/

相关文章:

vb6 - VB6-将变体转换为节点

c# - 如何从 C# 中的方法返回 VB6 Variant 类型的等效项

c++ - 如何创建三维动态数组

c++ - 代码块和 lambdas c++11

c++ - 异常处理 - 在没有任何处理程序的情况下抛出异常

c++ - Valgrind 错误 : Syscall param epoll_pwait(sigmask) points to unaddressable byte(s)

boost - 如何将 OGRLineString 注册为 boost 线串?

c++ - boost::lexical_cast 可以将字符串中的十六进制转换为整数吗?

c++ - Boost 无法在 Ubuntu 上使用 CMake 正确链接

c++ - 如何使用 std::variant 保证复制省略?