Checking an object for a combination of identities

Hi

Say I have an object E, which has multiple members - a bool B, an int I and a char C.

Now say I want E to have a member function (F) which takes in a combination of the above variables as parameters and for each parameter checks to ensure it matches the relevant members of E. So for example, F could could in a bool and a char and would return true if these variables were identical with B and C. Or it could take in an int and a bool or all three etc.

Clearly you could overload member functions (if the variable types were dfferent) but this would get very long. From some initial research I think that variadic templates are the way forward.

Before I look into variadic templates, I'd be grateful if someone could confirm this is the best approach for this. Or is there something else which I've missed?

Thanks
Some languages (e.g. python and Fortran) support named parameters and hence would do what you want even if they weren't different types. C++ doesn't natively, but there are some workarounds; see e.g.
https://rosettacode.org/wiki/Named_parameters
Last edited on
ok thanks

so variadic templates won't help me here. i'm guessing quite a few devs want to do something like the above - what's the general approach they take?
I think variadic templates might be able to do it, provided the types of the parameters are different (as in your case). You could pick off the last element each time and use typeid:
http://www.cplusplus.com/reference/typeinfo/type_info/operator==/
to compare with your bool, int, char types.

It might not stop you putting in repeated types (e.g. bool, char, bool) though.

You will gather that I haven't actually tried it!

The C++ link in the reference I gave earlier suggests that a boost library could do it, but I couldn't confirm that.
Last edited on
This is a really bodged job but it might do the sort of thing you are looking for. (I haven't bothered to put stuff in a struct, just chosen some values to compare with.)

Note: it should be able to check for bool, int, char - which may or may not be present and may be IN ANY ORDER. (This is what named parameters - aka "keyword arguments" - would do).

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 <typeinfo>
using namespace std;

bool boolValue = true;       // Values to check against
int  intValue  = 10;         //
char charValue = 'A';        //

template<typename T> bool check( T x )
{
   if ( typeid(T) == typeid(bool) ) return x == boolValue;
   if ( typeid(T) == typeid(int ) ) return x == intValue;
   if ( typeid(T) == typeid(char) ) return x == charValue;
   return false;
}

template<typename T, typename U> bool check( T x, U y )
{
   if ( typeid(x) == typeid(y) ) return false;
   return check( x ) && check( y );
}

template<typename T, typename U, typename V> bool check( T x, U y, V z )
{
   if ( typeid(x) == typeid(y) || typeid(y) == typeid(z) || typeid(x) == typeid(z) ) return false;
   return check( x ) && check( y ) && check( z );
}


int main()
{
   cout << boolalpha << check( true, 'A' ) << '\n';
   cout << boolalpha << check( 10, 'A' ) << '\n';
   cout << boolalpha << check( 10, 'A', false ) << '\n';
   cout << boolalpha << check( true, 'A', 1 ) << '\n';
   cout << boolalpha << check( 3, 'A' ) << '\n';
   cout << boolalpha << check( 'A' ) << '\n';
   cout << boolalpha << check( 'C' ) << '\n';
}
Last edited on
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
#include <optional>

struct A 
{
  bool b; char c; int i;

  constexpr bool compare(std::optional<bool> b0, 
                         std::optional<char> c0,
                         std::optional<int> i0) const noexcept
  {
    return (! b0.has_value() || *b0 == b) &&
           (! c0.has_value() || *c0 == c) &&
           (! i0.has_value() || *i0 == i); 
  }
}; 

int main()
{
    constexpr A a{ false, 'a', 42 };
    static_assert(  a.compare( false, 'a', 42 ));
    static_assert(! a.compare( true,  'a', 42 ));
    
    static_assert(  a.compare( std::nullopt, 'a', 42 ));
    static_assert(! a.compare( std::nullopt, 'b', 42 ));
    
    static_assert(  a.compare( std::nullopt, std::nullopt, std::nullopt ));
    static_assert(! a.compare( std::nullopt, std::nullopt, 9000 ));
}


http://coliru.stacked-crooked.com/a/7600e6bfc5bcc204
Last edited on
Topic archived. No new replies allowed.