Comparison tricks in C++

前端 未结 10 1873
礼貌的吻别
礼貌的吻别 2021-01-31 16:13

A class:

class foo{
public:
    int data;
};

Now I want to add a method to this class, to do some comparison, to see if its data is equal to on

10条回答
  •  南笙
    南笙 (楼主)
    2021-01-31 16:45

    The answers using std::initializer_list are fine, but I want to add one more possible solution which is exactly what you where trying with that C variadic in a type-safe and modern way: Using C++11 variadic templates:

    template
    bool any_equal( const foo& f , NUMBERS&&... numbers )
    {
        auto unpacked = { numbers... };
    
        return std::find( std::begin( unpacked ) , std::end( unpacked ) , f.data ) 
               != std::end( unpacked );
    };
    

    Of course this only works if all values passed are of the same type. If not the initializer list unpacked cannot be deduced nor initialized.

    Then:

    bool equals = any_equal( f , 1,2,3,4,5 );
    

    EDIT: Here is a are_same metafunction to ensure that all the numbers passed are of the same type:

    template
    struct are_same : public and_op::value...>
    {};
    

    Where and_op performs n-ary logical and:

    template
    struct and_op : public std::integral_constant::value>
    {};
    
    template<>
    struct and_op<> : public std::true_type
    {};
    

    This makes possible to force the usage of numbers of the same type in a simple way:

    template
    bool any_equal( const foo& f , NUMBERS&&... numbers )
    {
        static_assert( all_same::value , 
                       "ERROR: You should use numbers of the same type" );
    
    
        auto unpacked = { numbers... };
    
        return std::find( std::begin( unpacked ) , std::end( unpacked ) , f.data ) 
               != std::end( unpacked );
    };
    

提交回复
热议问题