【发布时间】:2019-08-29 06:49:53
【问题描述】:
为什么我们需要为正确的std::map 行为定义默认构造函数TConcrete()?
没有它,我得到以下结果:
>note: see reference to function template instantiation 'std::pair<const _Kty,_Ty>::pair<std::tuple<std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&>,std::tuple<>,0,>(_Tuple1 &,_Tuple2 &,std::integer_sequence<unsigned int,0>,std::integer_sequence<::size_t>)' being compiled
1> with
1> [
1> _Kty=std::string,
1> _Ty=TConcrete,
1> _Tuple1=std::tuple<std::basic_string<char,std::char_traits<char>,std::allocator<char>> &&>,
1> _Tuple2=std::tuple<>
1> ]
这是我的代码。我正在使用 C++03。
main.cpp
#include<iostream>
#include"TBuilder.h"
using namespace std;
int main()
{
TBuilder builder = TBuilder();
cout << builder.Get_Eb("B25");
cin.get();
return 0;
}
TBuilder.h
#pragma once
#include"TConcrete.h"
class TBuilder {
private:
TConcreteData concrete_data;
public:
TBuilder();
double Get_Eb(string);
};
TBuilder.cpp
#include"TBuilder.h"
TBuilder::TBuilder()
{
TConcrete B25 = TConcrete( "B25",2000,20,2 );
concrete_data["B25"] = B25;
}
double TBuilder::Get_Eb(string grade0)
{
return concrete_data[grade0].E_b;
}
TConcrete.h
#pragma once
#include<map>
#include<string>
#include "main.h"
using namespace std;
struct TConcrete {
string grade;
double E_b, R_b, R_bt;
TConcrete();
TConcrete(string, double,double,double);
};
typedef map<string, TConcrete> TConcreteData;
TConcrete.cpp
#include "TConcrete.h"
TConcrete::TConcrete()
{
}
TConcrete::TConcrete(string grade0, double E_b0, double R_b0, double Rb_t0)
{
grade = grade0;
E_b = E_b0;
R_b = R_b0;
R_bt = R_b0;
}
我阅读了std::map calls default constructor on [], copy constructor on insert() 的讨论,但使用insert() 也需要默认构造函数。使用insert()查看代码。
TConcrete.h(修改为insert())
#pragma once
#include<map>
#include<string>
#include "main.h"
#include<utility>
using namespace std;
struct TConcrete {
string grade;
double E_b, R_b, R_bt;
TConcrete();
TConcrete(string, double,double,double);
};
typedef map<string, TConcrete> TConcreteData;
typedef pair<string, TConcrete> TConcreteDataItem;
TBuilder.cpp(修改为insert())
#include"TBuilder.h"
TBuilder::TBuilder()
{
TConcrete B25 = TConcrete( "B25",2000,20,2 );
concrete_data.insert(TConcreteDataItem("B25",B25));
}
double TBuilder::Get_Eb(string grade0)
{
return concrete_data[grade0].E_b;
}
【问题讨论】:
-
你的
std::map在哪里? -
此代码不完整 - 您没有显示任何
std::map声明。但是假设 TConcreteData 是std::map的某种类型别名,如果访问的键不存在,std::map::operator[]会在映射中插入一个新对象。如果您不希望您的 TConcrete 类是默认可构造的,则必须使用其他函数,例如std::map::emplace -
什么是 TConcreteData?
-
@JamesPicone 你是对的。从 VS 移动代码时,我错过了 TConcrete.h 中的
typedef。已更正。 -
@Fëamarto 查看我对 JamesPicone 的回答