正确 std::map 行为的结构的默认构造函数
Default constructor of the structure for correct std::map behaviour
为什么我们需要为正确的 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;
}
我阅读了 讨论,但使用 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::operator[]
搜索指定的键,如果没有找到则为该键插入一个新的 default-constructed 值。
因此,语句 concrete_data["B25"]
总是 returns 有效的 TConcrete&
引用,这意味着如果需要,在允许您分配之前默认构造一个 TConcrete
对象您的 B25
变量设置为 found/inserted 值。
如果您想在地图中添加新键而不搜索该键是否已存在,请改用 std::map::insert()
或 std::map::emplace()
:
TConcrete B25( "B25", 2000, 20, 2 );
concrete_data.insert(std::make_pair("B25", B25));
TConcrete B25( "B25", 2000, 20, 2 );
concrete_data.emplace("B25", B25);
您需要默认构造函数,因为您使用的方式 std::map
需要它可能创建对象。如果您不以这种方式使用它,则不需要默认构造函数。
由于缺少默认构造函数,此代码将无法编译:
#include <map>
struct Struct
{
Struct(int) {}
};
int main()
{
std::map<std::string, Struct > m;
m["1"] = Struct(1);
Struct& s = m["1"];
}
[]
运算符 returns 对现有值的引用。如果该值不存在,则创建一个新值(使用默认构造函数)并返回对该值的引用。第一条语句可能看起来不像正在发生的事情,但实际上等同于:
Struct& s = m["1"];
s = Struct(1);
如果您使用 find
和 insert
,则不需要默认构造函数:
int main()
{
std::map<std::string, Struct > m;
m.insert(std::make_pair(std::string("1"), Struct(1)));
auto it = m.find("1");
if (it != m.end())
{
Struct& s = it->second;
}
}
为什么我们需要为正确的 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;
}
我阅读了 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::operator[]
搜索指定的键,如果没有找到则为该键插入一个新的 default-constructed 值。
因此,语句 concrete_data["B25"]
总是 returns 有效的 TConcrete&
引用,这意味着如果需要,在允许您分配之前默认构造一个 TConcrete
对象您的 B25
变量设置为 found/inserted 值。
如果您想在地图中添加新键而不搜索该键是否已存在,请改用 std::map::insert()
或 std::map::emplace()
:
TConcrete B25( "B25", 2000, 20, 2 );
concrete_data.insert(std::make_pair("B25", B25));
TConcrete B25( "B25", 2000, 20, 2 );
concrete_data.emplace("B25", B25);
您需要默认构造函数,因为您使用的方式 std::map
需要它可能创建对象。如果您不以这种方式使用它,则不需要默认构造函数。
由于缺少默认构造函数,此代码将无法编译:
#include <map>
struct Struct
{
Struct(int) {}
};
int main()
{
std::map<std::string, Struct > m;
m["1"] = Struct(1);
Struct& s = m["1"];
}
[]
运算符 returns 对现有值的引用。如果该值不存在,则创建一个新值(使用默认构造函数)并返回对该值的引用。第一条语句可能看起来不像正在发生的事情,但实际上等同于:
Struct& s = m["1"];
s = Struct(1);
如果您使用 find
和 insert
,则不需要默认构造函数:
int main()
{
std::map<std::string, Struct > m;
m.insert(std::make_pair(std::string("1"), Struct(1)));
auto it = m.find("1");
if (it != m.end())
{
Struct& s = it->second;
}
}