gpt4 book ai didi

c++ - 缩写相似的数据成员

转载 作者:行者123 更新时间:2023-11-30 02:45:03 25 4
gpt4 key购买 nike

下面的代码说明了这个问题:

struct Data {
int numFriends, numAcquaintances, numDates;
// etc...
};

enum Country {USA, Canada, China}; // etc...
enum Personality {Serious, Lazy, Funny}; // etc...
enum Height {SuperShort, Short, Medium, Tall, SuperTall};

class Religion {};

class Person {
std::map<Country, Data> countryStats;
std::map<Personality, Data> personalityStats;
std::map<Religion*, Data> religionStats;
std::map<Height, Data> heightStats; // And suppose there are 20 such similar data members

// The problem:
void insertNumFriends (Country country, int num) {countryStats[country].numFriends = num;}
void insertNumFriends (Personality personality, int num) {personalityStats[personality].numFriends = num;}
void insertNumFriends (Religion* religion, int num) {religionStats[religion].numFriends = num;}
// and tons of other necessary methods (how to capture all of these using templates?);

这是我想出的(不完整的)解决方案,即使注释掉的行可以编译,它仍然不是一个好方法,因为所有的 if 语句(事实上,它只是只要原来的方法):

#include <iostream>
#include <map>
#include <typeinfo>
#include <typeindex>

struct Data {
int numFriends, numAcquaintances, numDates;
// etc...
};

enum Country {USA, Canada, China, France}; // etc...
enum Personality {Serious, Lazy, Funny}; // etc...
enum Height {SuperShort, Short, Medium, Tall, SuperTall};

class Religion {};

template <typename T> // new struct here
struct Stats {
std::map<T, Data> map;
};

class Person {
Stats<Country> countryStats;
Stats<Personality> personalityStats;
Stats<Religion*> religionStats;
Stats<Height> heightStats; // And suppose there are 20 such similar data members
// template <typename T> static std::map<std::type_index, Stats<T>> statsMap; // illegal
public:
template <typename T>
void insertNumFriends (const T& t, int num) {
if (typeid(T) == typeid(Country)) {countryStats.map[t].numFriends = num;}
// lines below will not compile, and it's a terrible method anyway:
// else if (typeid(T) == typeid(Personality)) personalityStats.map[t].numFriends = num;
// else if (typeid(T) == typeid(Religion)) religionStats.map[t].numFriends = num;
// else if (typeid(T) == typeid(Height)) heightStats.map[t].numFriends = num;
}
void showAllStats() const { // for testing only
for (int COUNTRY = USA; COUNTRY <= France; COUNTRY++) {
auto it = countryStats.map.find(static_cast<Country>(COUNTRY));
if (it != countryStats.map.end())
std::cout << "Country " << COUNTRY << ": " << it->second.numFriends << " friends" << std::endl;
}
// etc...
}
};


int main() {
Person bob;
bob.insertNumFriends (USA, 5);
bob.insertNumFriends (France, 2);
// bob.insertNumFriends (Funny, 3); // won't compile because insertNumFriends<T> is not complete
bob.showAllStats(); // USA: 5 friends, France: 2 friends
}

什么是更好的(可行的解决方案)?非循环访问者模式或类似的东西?注意:Person 也有 name, age, countryOfOrigin, height 等数据成员...并且确实代表了一个人,而不仅仅是容器的接口(interface)(上面的容器数据成员是这个人的“记录”)。

最佳答案

一种可能的解决方案:模拟 C++1y 变量模板

定义一个保存数据的函数,在本例中为 map :

template<typename T>
std::map<T,Data>& map()
{
static std::map<T,Data> _map;

return _map;
}

现在只做一个通用的插入函数:

template<typename T>
void insert_data( const T& key , const Data& data )
{
map<T>()[key] = data;
}

关于c++ - 缩写相似的数据成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24842373/

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