【发布时间】:2021-08-24 23:06:25
【问题描述】:
此代码在 Visual Studio 2017 中引发编译错误:
#include <iostream>
#include <string>
using std::cin;
using std::cout;
template<class T>
class A
{
public:
A(T a);
~A() {}
#if 0
A(const A<T>&);
#else
A(A<T>&);
#endif
T t;
};
template<class T>
A<T>::A(T a) : t(a) {}
template <class T>
#if 0
A<T>::A(const A<T>& a)
#else
A<T>::A(A<T>& a)
#endif
{
t = a.t;
std::cout << "In A copy constructor.\n";
}
int main()
{
std::string s;
A<int> a1(11);
A<double> a2(2.71);
#if 1
A<double> a3 = A<double>(a2); //gives C2440 when copy constructor argument is not const.
//compiler message is: 'initializing': cannot convert from 'A<double>' to 'A<double>'
#else
A<double> a3{a2}; //works when copy constructor argument is not const.
#endif
std::cout << a3.t << "\n";
std::cout << "Press ENTER to exit.\n";
std::getline(std::cin, s);
}
C2440 编译失败:'initializing': cannot convert from 'A<double>' to 'A<double>'. 当前两个 #if 0s 更改为 #if 1s(选择带有 const 参数的复制构造函数)时,程序编译并运行。此外,如果所有条件编译都选择了#if 0,则程序编译并运行。
This question 没有回答我的问题。根据 cppreference.com,具有非常量参数的复制构造函数是可能的:
类T的拷贝构造函数是一个非模板构造函数,它的第一个参数是T&, const T&, volatile T&, or const volatile T&, 要么没有其他参数,要么剩下的参数都有默认值。
当我写的时候,带有非常量参数的复制构造函数仍然可以工作
A<double> a3{a2};
那么为什么要初始化
A<double> a3 = A<double>(a2);
当复制构造函数的参数不是 const 时不起作用?
【问题讨论】:
-
因为不允许修改临时参数,这就是非常量引用参数的意思,“我要修改参数。”
-
为了改进问题,请发布可以不加修改地编译的版本以给出错误(而不是发布正确的版本并描述给出错误的修改)。也没有必要包含非错误版本。
-
注意 - 由于 C++17,
A<double> a3 = A<double>(a2);完全等同于A<double> a3{a2};,但可能您使用的编译器版本不支持 C++17 或未设置为模式 -
当我使用 C++17 编译时得到相同的结果:
A<double> a3{a2}有效,而当我选择不带 const 参数的复制构造函数时,A<double> a3 = A<double>(a2)无法编译。 -
啊,很好发现@M.M.我可以确认,使用 clang 和 gcc,当设置
-std=c++17时,编译不会出错。
标签: c++ visual-c++ variable-assignment