1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
struct item : std::tuple< std::string, int, int >
{
using std::tuple< std::string, int, int >::tuple ;
std::string name() const { return std::get<std::string>(*this) ; }
int id() const { return std::get<1>(*this) ; }
int value() const { return std::get<2>(*this) ; }
enum member { NAME, ID, VALUE }; // *** caveat: somewhat brittle
// needs to be updated if a new member is added
template < member m > decltype(auto) get() const { return std::get<m>(*this) ; }
};
template < item::member m, typename ITEM_SEQ, typename T >
auto find( ITEM_SEQ& seq, const T& value )
{
for( auto& x : seq ) if( x.template get<m>() == value ) return std::addressof(x) ;
return decltype( std::addressof( *std::begin(seq) ) ){} ;
}
int main()
{
std::vector<item> items { { "one", 1, 1 }, { "two", 2, 20 }, { "three", 3, 30 } } ;
auto ptr = find<item::NAME>( items, "two" ) ;
if(ptr) std::cout << ptr->name() << '\n' ; // two
ptr = find<item::VALUE>( items, 30 ) ;
if(ptr) std::cout << ptr->name() << '\n' ; // three
ptr = find<item::ID>( items, 37 ) ;
if(ptr) std::cout << ptr->name() << '\n' ;
else std::cout << "not found\n" ; // not found
}
|