如何在C++中传递结构体成员作为参数实现通用排序?
Hey Alex,
Great question! The core issue here is making your sorting logic reusable instead of writing duplicate code for each Weather struct member. Let’s walk through two clean, idiomatic C++ solutions to solve this:
Method 1: Use Modern Lambdas with std::sort (Recommended for C++11+)
Instead of writing your own bubble sort (which is inefficient), we’ll leverage the standard library’s std::sort and pass custom comparison logic via lambda expressions. This keeps your code concise and avoids repetition.
Here’s the modified version of your code:
#include <QtCore/QCoreApplication> #include<iostream> #include<cmath> #include<cstdlib> #include<cstdio> #include<cctype> #include<iomanip> #include<algorithm> // Required for std::sort using namespace std; struct Weather { char Date[12]; int Temperature; int Pressure; int Humidity; }; Weather arr[30] = { {"2002.12.15", -4, 115, 5}, {"2014.5.3", 10, 101, 10}, {"2001.8.3", 15, 68, 12}, {"2013.11.9", 12, 123, 3}, }; int size = 4; void showArr() { for(int i =0;i < size;i++) { cout << setw(12) << arr[i].Date << " - Date" << setw(15) << arr[i].Temperature << " - Temperature" << setw(12) << arr[i].Pressure << " - Pressure" << setw(15) << arr[i].Humidity << " - % Humidity" << endl; } } // Generic sort function that accepts any comparator template<typename Comparator> void sortWeather(Comparator comp) { sort(arr, arr + size, comp); // std::sort handles the heavy lifting } void Sort_ind() { int k; cout <<"0 - Exit\n"; cout <<"1 - Sort temperature\n"; cout <<"2 - Sort pressure\n"; cout <<"3 - Sort humidity\n"; cin >>k; switch(k) { case 0: exit(0); case 1: // Lambda to sort by temperature (ascending order) sortWeather([](const Weather& a, const Weather& b) { return a.Temperature < b.Temperature; }); break; case 2: // Lambda to sort by pressure sortWeather([](const Weather& a, const Weather& b) { return a.Pressure < b.Pressure; }); break; case 3: // Lambda to sort by humidity sortWeather([](const Weather& a, const Weather& b) { return a.Humidity < b.Humidity; }); break; default: cout << "Invalid option! Try again." << endl; return; } // Display sorted results cout << "\nSorted Output:\n"; showArr(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); Sort_ind(); return a.exec(); }
Key Improvements:
- No duplicate sorting code: The
sortWeathertemplate function works with any comparison logic you pass it. - Efficient sorting:
std::sortuses a highly optimized algorithm (quicksort/introsort) instead of your hand-written bubble sort. - Clean comparisons: Lambdas keep the comparison logic right where you use it, making the code easy to read and modify.
- Simplified swapping:
std::sortswaps entireWeatherobjects automatically—no need to swap each member individually!
Method 2: Function Pointers (For C++03 Compatibility)
If you’re stuck with an older C++ standard that doesn’t support lambdas, you can define separate comparison functions and pass their pointers to the sort function:
// Add these comparison functions above sortWeather bool compareTemperature(const Weather& a, const Weather& b) { return a.Temperature < b.Temperature; } bool comparePressure(const Weather& a, const Weather& b) { return a.Pressure < b.Pressure; } bool compareHumidity(const Weather& a, const Weather& b) { return a.Humidity < b.Humidity; } // Modify sortWeather to accept a function pointer void sortWeather(bool (*comp)(const Weather&, const Weather&)) { sort(arr, arr + size, comp); } // Update the switch case calls: case 1: sortWeather(compareTemperature); break; case 2: sortWeather(comparePressure); break; case 3: sortWeather(compareHumidity); break;
This achieves the same reuse goal but is less concise than the lambda approach.
Whichever method you choose, you’ll eliminate redundant code and make your program easier to maintain. If you want to sort in descending order, just flip the < to > in the comparison logic!
内容的提问来源于stack exchange,提问作者Alex Delarge

