问题
I am trying to find way to design a class template so that an int
value is passed, and several function signatures as well as argument lists are dependent on this value.
Particularly, considering MyClass
:
template <int N>
class MyClass {
typedef SomeType<int, int, int, /* ... N times*/ > MyDepType;
myFunction(std::string arg0, std::string arg1, /* ...*/ std::string argN) { /* do stuff */};
public:
MyClass() {
someFunction(float arg0, float arg1, /* ...*/ float argN); // <
someOtherFunction(boost::bind(&MyClass::myFunction, this, _1, _2, /*...*/ _N));
};
};
I'd like to be able to express both the private typedef call, the signature of myFunction
and the argument list passed to external functions someFunction
and someOtherFunction
, which I can't edit/rewrite.
Is there a way to achieve this, using the C++11 standard?
回答1:
You could use a trick like in this post (Produce std::tuple of same type in compile time given its length by a template argument) to produce a tuple of N elements.
template <int N, typename T>
struct tuple_n_impl {
template <typename... Ts>
using type = typename tuple_n_impl<N - 1, T>::template type<T, Ts...>;
};
template <typename T>
struct tuple_n_impl<0, T> {
template <typename... Ts>
using type = std::tuple<Ts...>;
};
template <int N, typename T>
using tuple_n = typename tuple_n_impl<N, T>::template type<>;
template <int N>
class MyClass {
void int_function(tuple_n<N, int>&& ints);
void float_function(tuple_n<N, float>&& floats);
template <typename T>
void any_function(tuple_n<N, T>&& elements);
};
回答2:
You might use std::index_sequence
(C++14, but implementation in C++11 can be found on SO):
template <std::size_t, typename T>
using always_t = T;
template <std::size_t ... Is>
class MyClassImpl {
using MyDepType = SomeType<always_t<Is, int>...>;
void myFunction(always_t<Is, std::string>... args) { /* do stuff */}
public:
MyClass() {
void someFunction(always_t<Is, std::float>... args);
someOtherFunction([this](always_t<Is, const std::string&>... args) {
return myFunction(args...);
});
//
std::array<std::string, sizeof...(Is)> strings = {std::to_string(Is)...};
myFunction(strings[Is]...);
};
};
template <std::size_t N>
using MyClass = MyClassImpl<std::make_index_sequence<N>>;
来源:https://stackoverflow.com/questions/61990155/how-to-use-class-template-argument-to-change-argument-calls-and-function-signatu