Home > Mobile >  Default arguments for member function of templated class
Default arguments for member function of templated class

Time:03-30

Let's say I have something like this bit of (duplicated) code that I'd like to refactor using a template:

#include <iostream>
#include <algorithm>
#include <set>

struct IntFoo {
  auto f(int arg, std::set<int> s = {1, 2, 3}) {
    return std::find(s.begin(), s.end(), arg) != s.end();
  }
};

struct FloatFoo {
  auto f(float arg, std::set<float> s = {4.0f, 5.0f, 6.0f}) {
    return std::find(s.begin(), s.end(), arg) != s.end();
  }
};

int main() {
  std::cout << IntFoo().f(3) << std::endl;
  std::cout << FloatFoo().f(4.0f) << std::endl;
}

As you can see, beyond the variance in type there is also the change in the default arguments given to f()'s second parameter.

Best I could come up with was this:

#include <iostream>
#include <algorithm>
#include <set>

template<typename T, typename Def>
struct Foo {
  auto f(T arg, std::set<T> s = Def::defaults){
    return std::find(s.begin(), s.end(), arg) != s.end();
  }
};

struct FooIntDefaults {
  static constexpr std::initializer_list<int> defaults{1, 2, 3};
};

struct FooFloatDefaults {
  static constexpr std::initializer_list<float> defaults{4.0f, 5.0f, 6.0f};
};

using IntFoo = Foo<int, FooIntDefaults>;
using FloatFoo = Foo<float, FooFloatDefaults>;

This works, but is a bit verbose. I don't fancy these helper structs much.

Ideally I'd like to pass the default arguments in the using line somehow. Is there some better way?

CodePudding user response:

You can use parameter pack for specifying default arguments, e.g.

template<typename T, T... defaults>
struct Foo {
  auto f(T arg, std::set<T> s = {defaults...}){
    return std::find(s.begin(), s.end(), arg) != s.end();
  }
};

using IntFoo = Foo<int, 1, 2, 3>;              // specify default arguments when defining type
using FloatFoo = Foo<float, 4.0f, 5.0f, 6.0f>; // specify default arguments when defining type

LIVE

BTW: Note that float can't be used as non-type template parameter before C 20.

  • Related