Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

c++ - Any metaprogramming way to generate overloads for various numbers of template parameters?

I'm trying to create a set of function templates that can take different types and numbers of parameters, like this:

template <T0>
void call(T0 arg0);

template <T0, T1>
void call(T0 arg0, T1 arg1);

template <T0, T1, T2>
void call(T0 arg0, T1 arg1, T2 arg2);

template <T0, T1, T2, T3>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3);

template <T0, T1, T2, T3, T4>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4);

[...]

The parameters are all treated the same within the functions (as arguments to a single-parameter template function). This is for a library, so extra effort on my part is acceptable, if it means less effort or a more pleasing interface for the library user.

I've had to do this several times for different projects, and I'm heartily tired of having to manually write all of them by hand. It gets worse when I don't know beforehand the maximum number of parameters the project using the library will need.

Before I start writing a Python script to generate all of the overloads, is there some metaprogramming way to have the compiler do it for me instead?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There is no standard way of doing this, but it can be done in C++0x, the upcoming (but not-yet-official) standard using a technique called 'variadic templates.' See here for an example by yours truly. Quoting myself:

#include <iostream>

template<typename Format>
void meheer(const Format& format) {
  std::cout << format << std::endl;;
}

template<typename Format, typename Elt, typename ... Args>
void meheer(const Format& format, const Elt & e, const Args&... args) {
  std::cout << format << e;
  meheer(format, args...);
}

template<typename Format, typename ... Args>
void ohai(const Format& format, const Args&... args) {
  meheer(format, args...);
}

int main(int argc, char ** argv) {
  ohai(1,2,3);

  return EXIT_SUCCESS;
}

Output: (compiled with GCC, with flag -std=c++0x)

12131

Conceptually, this is similar to a basic recursive match using pattern matching (as in a functional language), but unrolled at compile time.

If you do not want to include a not-yet-standard feature, then the 'many similar definitions using python script' approach is not a bad way to go. The boost libraries use a similar approach, but tend to rely on preprocessor macros. If you're interested, have a look at the source for Boost.Variant, which does this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...