简体   繁体   中英

Default arguments for member function of templated class

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?

You can use parameter pack for specifying default arguments, eg

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM