1

Is there a way to write a function with two templated types;

  • taking two arguments, such that
  • the second argument is set to a default value if the function is called with only one argument?

The following does not work:

#include <iostream> template <class A, class B> void f (A a, B b = 0) { std::cout << "Hello world!" << std::endl; } int main () { int i; f (i); } 

In other words, I would like to have a "template-analogy" to

template <class A> void f (A a, int b = 0) { std::cout << "Hello world!" << std::endl; } 
5
  • Well, it doesn't know what type B is, so how can it set a default value for it? Commented Jul 28, 2015 at 20:53
  • It could deduce B from the default value. If it did so ... If I call f by f(i,0), then it does. Commented Jul 28, 2015 at 20:53
  • If it could deduce the type of B from the default, then why would you make it a template parameter? Commented Jul 28, 2015 at 20:54
  • Sometimes I want to write f(0,"something"). Commented Jul 28, 2015 at 20:54
  • 1
    Overload with a template <class A> void f (A a); Commented Jul 28, 2015 at 20:56

4 Answers 4

4

Yes, if you are prepared to give B a default type as well (and use C++11).

template <class A, class B = int> void f (A a, B b = B{}) { std::cout << "Hello world!" << std::endl; } int main () { int i; f (i); } 

Alternatively overload f and provide your defaults as required.

Sign up to request clarification or add additional context in comments.

Comments

3

Hope this is what you are looking for, so if f is not passed a second argument then B will be an int and b will be 0. Though that can be changed.

#include <iostream> template <class A, class B = int> void f (A a, B b = 0) { std::cout << "Hello world!" << std::endl; } int main () { int i = 42; f(i); f(i, "something"); } 

Comments

0

Overload f in such a way that it uses the default value you want:

#include <iostream> template <class A, class B> void f (A a, B b) { std::cout << "Hello world!" << std::endl; } template <class A> void f (A a) { f(a, 0); } int main () { int i; f (i); } 

You can forward a if this implementation is a performance concern.

2 Comments

I think this is cleanest solution.
Given the sample code, it would be move, not forward a.
-2

You can use the default constructor for the B type. It will work for primitive data types as well:

include <iostream> include <string> using std::cout; using std::endl; using std::string; class TestClass { public: TestClass() { cout << "TestClass()" << endl; } }; std::ostream& operator<<(std::ostream &os, const TestClass &tcl) { os << "TestClass" << endl; return os; } template <class A, class B> void f (A a, B b = B()) { cout << "Hello world! b=" << b << endl; } int main(int argc, char *argv[]) { cout << "File: " << __FILE__ << endl; f<int, int>(1); f<int, char>(1); f<int, string>(1); f<int, TestClass>(1); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.