How to check if two template parameters match?

How can I change the following function template to return 42 if the template parameters T and U are exactly the same types?

 template<typename T,typename U> int Foo() { return 0; } 
+4
source share
4 answers

Using std::is_same can provide the desired behavior:

 #include <type_traits> template<typename T,typename U> int Foo() { return std::is_same<T, U>::value ? 42 : 0; } 
+10
source

The idiomatic way is to delegate the work to an auxiliary function object in the detail namespace, which you can partially specialize for the case when T matches U (or for any other compile-time pattern that you can use in class templates).

 namespace detail { template<typename T, typename U> struct foo { int operator()() const { return 0; } }; template<typename T> struct foo<T, T> { int operator()() const { return 42; } }; } // namespace detail template<typename T, typename U> int Foo() { return detail::foo<T, U>()(); } 

For functions that also have output arguments (for example, a Foo(T x, U y) ), this combines the ability of an argument to subtract function templates and the ability to specialize class templates, without each user being wiser (well, you you need an agreement that they do not call anything from namespace detail directly)

+4
source

Just for completeness of answers, here is how you can make this choice at compile time without classes:

 namespace detail { int Foo(std::true_type) { return 42; } int Foo(std::false_type) { return 0; } } template <typename T, typename U> int Foo() { return detail::Foo(std::is_same<T, U>()); } 

This fork at compile time is important when two different code paths have different requirements for your arguments (but not in this case). For example, in one path you use the member function x() and in another y() ; or, as you already noted, even completely "different" functions.

This is much easier for me than managing a class.

+2
source

How about this?

 #include <iostream> template<typename T,typename U> struct Foo { int operator()() { return 0; } }; template<typename T> struct Foo<T, T> { int operator()() { return 42; } }; int main() { std::cout << Foo<int, int>()() << std::endl; std::cout << Foo<int, double>()() << std::endl; } 
+1
source

All Articles