Depending on the class template parameter, specify or not define a function in the class

Suppose we have a class:

template <class Type> class A { public: void function1(float a, Type b); void function1(float a, float b); }; 

Now create an instance of the class as follows:

 A<int> a; 

Well, this class will have 2 overloaded functions with these parameters: (float a, int b); (float a, float b);

But when you instantiate the class as follows:

 A<float> a; 

You get a compilation error:

member function redeclared.

So, depending on the type of Type, I don’t want (or don’t want) the compiler to define a function, something like this:

 template <class Type> class A { public: void function1(float a, Type b); #if Type != float void function1(float a, float b); #endif }; 

But of course, the syntax above does not work. Is it possible to perform such a task in C ++? If possible, provide an example.

+8
c ++ function parameters templates
source share
3 answers

You can use specialized specialization:

 template <class Type> class A { public: void function1(float a, Type b) { } void function1(float a, float b) { } }; template <> class A<float> { public: void function1(float a, float b) { } }; // ... A<int> a_int; a_int.function1(23.4f, 1); a_int.function1(23.4f, 56.7f); A<float> a_float; a_float.function1(23.4f, 56.7f); 

--- EDIT ---

If you have a large number of common functions, you can do something like this:

 class AImp { public: void function1(float a, float b) { } void function1(float a, double b) { } void function1(float a, const std::string& b) { } // Other functions... }; template <class Type> class A : public AImp { public: void function1(float a, Type b) { } using AImp::function1; }; template <> class A<float> : public AImp { }; // ... A<int> a_int; a_int.function1(23.4f, 1); a_int.function1(23.4f, 56.7f); a_int.function1(23.4f, 56.7); a_int.function1(23.4f, "bar"); A<float> a_float; a_float.function1(23.4f, 56.7f); a_float.function1(23.4f, 56.7); a_float.function1(23.4f, "bar"); 
+8
source share

You can use some C++11 std::enable_if :

 template <class Type> class A { public: template<typename t = Type, typename std::enable_if<!std::is_same<t, float>::value, int>::type = 0> void function1(float a, Type b) { } void function1(float a, float b) { } }; 
+8
source share

Use SFINAE:

 #include <iostream> #include <type_traits> template <typename Type> struct Foo { template <typename T = Type> void function1(float a, float b, typename std::enable_if<!std::is_same<T, float>::value>::type *c = 0) { std::cout << "float\n"; } void function1(float a, Type b) { std::cout << "type\n"; } }; int main() { Foo<float> f; f.function1(1, 1); f.function1(1.0f,1.0f); Foo<int> g; g.function1(1,1); g.function1(1.0f,1.0f); g.function1(1.0,1.0); // warning! } 

Output:

 type type type float type 

You will need C ++ 11 mode to enable the default template parameter in the function template. And also get enable_if and is_same , although you could get enable_if from Boost.

"A warning!" because your source code is g.function1(1.0,1.0); was ambiguous. Overloading without templates is now preferred. You can make it ambiguous by doing

  template <typename T = Type> void function1(float a, Type b, typename std::enable_if<true>::type *c = 0) { std::cout << "type\n"; } 
+2
source share

All Articles