【发布时间】:2011-06-06 08:30:59
【问题描述】:
使用 MSVC2010...
我有一个包装 std::string 的结构,定义了标准移动 ctor,以及一个完美的转发 ctor,用于将参数转发到 std::string ctor。
struct Wrapper
{
std::string value;
Wrapper()
{
}
Wrapper( Wrapper const& rhs )
:value(rhs.value)
{
}
Wrapper( Wrapper&& rhs )
:value(std::move(rhs.value))
{
}
Wrapper& operator=( Wrapper const& rhs )
{
value = rhs.value;
return *this;
}
Wrapper& operator=( Wrapper&& rhs )
{
value = std::move(rhs.value);
return *this;
}
template<typename StringT>
Wrapper( StringT&& value )
:value(std::forward<StringT>(value))
{
}
};
但现在看来我无法从另一个包装器复制构造一个包装器
Wrapper w0;
Wrapper w1(w0);
这会导致指向完美转发 ctor 的编译错误,说它无法将 Wrapper 转换为 std::string。这是正确的行为吗?编译器不应该调用复制ctor,而不是模板化重载吗?
1>t:\depot\warp\code\apps\pf_test\main.cpp(56): error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'Wrapper' to 'const std::basic_string<_Elem,_Traits,_Ax> &'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> Reason: cannot convert from 'Wrapper' to 'const std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> t:\depot\warp\code\apps\pf_test\main.cpp(63) : see reference to function template instantiation 'Wrapper::Wrapper<Wrapper&>(StringT)' being compiled
1> with
1> [
1> StringT=Wrapper &
1> ]
1>
如果我定义另一个复制 ctor,一个对 Wrapper 进行非常量引用的复制 ctor(如下所示),那么一切似乎都很好......这是前进的方向吗?还是我搞砸了什么?或者这是 VS2010 的 bug?
Wrapper( Wrapper& rhs )
:value(rhs.value)
{
}
【问题讨论】:
-
您知道,您不需要手写所有这些构造函数。他们增加了使用 'Wrapper() = default;' 的能力句法。它会为您提供默认的构造函数和赋值运算符(您需要为所需的每个 ctr/op 执行此操作)。
-
感谢您的提示 - VC2010 似乎还不支持此功能
-
对不起,我有时会忘记,因为我主要使用 gcc。
标签: c++11