Thread: Using type_traits for choosing b/w more than 2 properties:

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    203

    Using type_traits for choosing b/w more than 2 properties:

    I made a type_traits working example that selects the print function from two alternatives depending on the compile-time type specification:
    Coliru Viewer
    I want to extend this to choosing between three (or more) types at compile time where either
    (a) two of the types are in turn inherited from a common base class:
    Coliru Viewer
    error: ambiguous call of overloaded function, or ...
    (b) two separate types without inheritance:
    Coliru Viewer
    error: invalid initialization of reference of type 'a' from expression of type 'b' and vice-versa
    Sure, I could explicitly specialize the templates for the two separate types but my question is whether type_traits only handles either-or cases or else how can it be extended to handle multiple types with/out inheritance?
    Many thanks

  2. #2
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    You can use enable_if and the like in type_traits. There's is_base_of, is_same, tons of stuff you can use with enable_if to give you proper overload resolution.

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    John - thanks for the suggestions, I'll be able to follow up early next week and report back then

  4. #4
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    I used std::true_type, std::false_type as base classes for the predicate that distinguishes types depending upon a pre-defined criterion. This works:
    Coliru Viewer
    However I was not able to implement it using std::enable_if though reading the literature it seems I should have. Facing two main problems in this regard: (a) compiler can't find the matching function call for data types for which the predicate is enabled and (b) how to implementing the template function for non-enabled types. Here's my attempt in case anyone has some feedback:
    Coliru Viewer
    And to make enable_if work I was trying to following this article:
    SFINAE and enable_if - Eli Bendersky's website
    Thank you

  5. #5
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Templates can have ugly error messages :P
    Code:
    main.cpp:21:28: note:   template argument deduction/substitution failed:
    main.cpp:31:13: note:   couldn't deduce template parameter 'T'

    I made your code work, I just had to manually specify the template parameter.
    Code:
        // print(x);
        print<Squared>(sq);
        print<Cubed>(cu);

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    why not make Squared and Cubed derive from a common base such as Printable, which has a pure virtual function print()?
    What can this strange device be?
    When I touch it, it gives forth a sound
    It's got wires that vibrate and give music
    What can this thing be that I found?

  7. #7
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Using interface-based programming like Elkvis suggests would be a good idea. You can then use enable_if with is_base_of then.

  8. #8
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    John, thanks for the nudge in the right direction. Now std::enable_if (or std::enable_if_t) works:
    Coliru Viewer
    Though I'm still puzzled why the compiler can't deduce the argument type and needs the additional type specifiers
    Elkvis/(later) John - yes, inheritance was one of the ways I'd set out in the OP (second link there) but wanted to get the actual implementation with non-member, non-friend methods if possible

  9. #9
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I think it's because you're using a derived type in your argument signature.

    Instead, you'd probably get type deduction if you put your enable if in the template signature or the return signature.

    Code:
    template <
      typename T,
      typename = std::enable_if_t<has_overload<T>::value>
    >
    auto my_function(T const& whatever) -> void
    {
      /* ... */
    }
    
    // or...
    
    template <typename T>
    auto my_function(T const& whatever) -> std::enable_if_t<has_overload<T>::value>
    {
      /* ... */
    }

  10. #10
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I tried messing around a bit more and it seems like this might be the wrong type of design. Elkvis' advice might actually just be the most sane way to go.

  11. #11
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    some progress towards dropping the type qualifiers when using std::enable_if but not quite there yet:
    Coliru Viewer
    the problem that remains is how to make print() work for types, such as POD, for which the predicate has_overload is false. removing the comments tag from the following line gives error message that it is a redefinition of print():
    Code:
    template <typename T, typename = typename std::enable_if<!has_overload<T>::value>::type> void print (T& t) { std::cout << t << "\n";}

  12. #12
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Unfortunately, it looks like the best way is to go with how you had it before with the enable_if in the function signature and specifying the template type.

  13. #13
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    John - thanks for all your help. There's also the other method based on std::true_type, std::false_type I'd mentioned earlier Coliru Viewer
    Horses for courses I suppose ...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 04-05-2015, 11:42 AM
  2. about properties
    By joaquim in forum C++ Programming
    Replies: 62
    Last Post: 02-06-2014, 10:51 AM
  3. Choosing a GPS
    By laserlight in forum General Discussions
    Replies: 14
    Last Post: 11-20-2009, 11:12 AM
  4. No properties in c++?
    By MisterT in forum C++ Programming
    Replies: 19
    Last Post: 08-06-2006, 08:54 AM
  5. FPS properties.
    By DarkBrute in forum Game Programming
    Replies: 24
    Last Post: 02-03-2005, 07:41 PM

Tags for this Thread