gpt4 book ai didi

c++ - RValue、模板解析和复制构造函数(在 Visual C++ 2010 中)

转载 作者:太空狗 更新时间:2023-10-29 21:06:44 26 4
gpt4 key购买 nike

我正在构造一个简单的容器类,但遇到了一些问题(重新组装 Visual C++ 2010, rvalue reference bug? 中的那些)

#include <cassert>
#include <utility>

template<typename T0>
class MyType {
public:
typedef T0 value_type;

// Default constructor
MyType() : m_value() {
}

// Element constructor
explicit MyType(const T0 &c_0) : m_value(c_0) {
}

template<typename S0>
explicit MyType(S0 &&c_0) : m_value(std::forward<S0>(c_0)) {
}

// Copy constructor
MyType(const MyType &other) : m_value(other.m_value) {
}

MyType(MyType &&other) : m_value(std::forward<value_type>(other.m_value)) {
}

// Copy constructor (with convertion)
template<typename S0>
MyType(const MyType<S0> &other) : m_value(other.m_value) {
}

template<typename S0>
MyType(MyType<S0> &&other) : m_value(std::move(other.m_value)) {
}

// Assignment operators
MyType &operator=(const MyType &other) {
m_value = other.m_value;
return *this;
}

MyType &operator=(MyType &&other) {
m_value = std::move(other.m_value);
return *this;
}

template<typename S0>
MyType &operator=(const MyType<S0> &other) {
m_value = other.m_value;
return *this;
}

template<typename S0>
MyType &operator=(MyType<S0> &&other) {
m_value = std::move(other.m_value);
return *this;
}

// Value functions
value_type &value() {
return m_value;
}

const value_type &value() const {
return m_value;
}

private:
template<typename S0>
friend class MyType;

value_type m_value;
};

int main(int argc, char **argv) {
MyType<float> t1(5.5f);
MyType<double> t2(t1);

return 0;
}

以上代码报错如下:

1>ClCompile:
1> BehaviorIsolation.cpp
1>behaviorisolation.cpp(18): error C2440: 'initializing' : cannot convert from 'MyType<T0>' to 'double'
1> with
1> [
1> T0=float
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> behaviorisolation.cpp(78) : see reference to function template instantiation 'MyType<T0>::MyType<MyType<float>&>(S0)' being compiled
1> with
1> [
1> T0=double,
1> S0=MyType<float> &
1> ]
1>behaviorisolation.cpp(18): error C2439: 'MyType<T0>::m_value' : member could not be initialized
1> with
1> [
1> T0=double
1> ]
1> behaviorisolation.cpp(73) : see declaration of 'MyType<T0>::m_value'
1> with
1> [
1> T0=double
1> ]
1>
1>Build FAILED.

如何在不使用链接问题中描述的技巧的情况下补救此错误?

谢谢!

编辑:最让我困惑的是为什么两个专门的构造函数中的任何一个都没有被调用。他们更适合这个电话。

  // Copy constructor (with convertion)
template<typename S0>
MyType(const MyType<S0> &other) : m_value(other.m_value) {
}

template<typename S0>
MyType(MyType<S0> &&other) : m_value(std::move(other.m_value)) {
}

最佳答案

您的链接问题已经回答了这个问题。让我们定义

typedef MyType<float>  MF;
typedef MyType<double> MD;

当你说 MD t2(t1); ,你会喜欢调用构造函数 MF::MF(const MD &) .但是,构造函数 template <typename T> MF::MF(T&&)匹配得更好,因为它需要 T = MD&从而解析为 MF::MF(MD&) , 由于缺少 const 而匹配得更好.

要解决这个问题,您基本上应该摆脱 MF(T&&)构造函数,正如霍华德已经建议的那样。由于无论如何您只打算为值构造函数,因此我的第一个建议是将签名更改为 MF(const T &) ,这已经可以解决您的问题。另一种解决方案是添加一个带有签名的构造函数 MF(MD&) (非常量)。不过,这很丑陋。最后,您可以在调用站点显式调用构造函数:MD t2(MF(t1)) , 或 MD t2(std::forward<MF>(t1))甚至 MD t2(std::move(t1)) ,如果这是一个选项。

最后请注意,如果您只处理原始成员,则显式移动不会有任何好处,因此您最好不要费心单独定义所有这些构造函数。

关于c++ - RValue、模板解析和复制构造函数(在 Visual C++ 2010 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6990173/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com