Branch by template parameter in function?

I have a template function, and at some point I would like to have a different code depending on the template parameter:

template <typename T>
void function(const T &param) {
    // generic code here...

    // pseudo-code:
    if constexpr isinstance(param, Banana) {
        param.peel();
    } else if constexpr isinstance(param, Apple) {
        // do nothing, Apple has no method `peel`
    }
}

I do not want to specialize the whole function, since most of the code is shared. The statement I want to insert is a random measure of temporary debugging. I know that it would be right to create an overloaded function doPeeland call this instead:

void doPeel(const Banana &param) { param.peel(); }
void doPeel(const Apple &param) {}

But I'm curious if there is a way to tell at compile time, in a function, what (type specialization) the type of the given variable ... is to use operators that compile for just one type?

, - constexpr - ? - lambdas - lambdas , . ?

+4
2

++ 14 if constexpr lambda, . :

#include <type_traits>
#include <iostream>

template <bool B>
struct constexpr_if {
   template <class Lambda, class T>
   static void then(Lambda l, T&& value) { }
};

template <>
struct constexpr_if<true> {
   template <class Lambda, class T>
   static void then(Lambda l, T&& value) {
      l(std::forward<T>(value));
   }
};


struct Banana {
   void peel() const {
     std::cout << "Banana::peel" << std::endl;
   }
};

struct Apple {
};

template <typename T>
void function(const T &param) {
    constexpr_if<std::is_same<T, Banana>::value>::then([&](auto &p){
       p.peel();
    }, param);
}

int main() {
  function(Banana{});
  function(Apple{});
}
+3

++ 17 if constexpr:

template<typename T>
void foo(T const& t)
{
    if constexpr(is_same<decay_t<T>, int>::value) {
        cout << __PRETTY_FUNCTION__ << " " << t * 2 << endl;
    } else {
        cout << __PRETTY_FUNCTION__ << endl;
    }
}


++ 14 - :

template<typename T>
void foo(T const& t)
{
    conditional_eval<is_same<decay_t<T>, int>>([=](auto){
        cout << __PRETTY_FUNCTION__ << " " << t * 2 << endl;
    },[](auto){
        cout << __PRETTY_FUNCTION__ << endl;
    });
}

conditional_eval :

template<typename IfTrue, typename IfFalse>
void conditional_eval_impl(std::true_type, IfTrue&& t, IfFalse&&) {
    t(0);
}

template<typename IfTrue, typename IfFalse>
void conditional_eval_impl(std::false_type, IfTrue&&, IfFalse&& f) {
    f(0);
}

template<typename Tag, typename IfTrue, typename IfFalse>
void conditional_eval(IfTrue&& t, IfFalse&& f) {
    conditional_eval_impl(Tag{}, std::forward<IfTrue>(t), std::forward<IfFalse>(f));
}

+2

Source: https://habr.com/ru/post/1658675/


All Articles