I want a helper function to instantiate a class for me. Currently it cannot compile in clang (though it compiles work in gcc), but I need it to work in clang as well. Currently I'm using clang version 6.0.0-1ubuntu2
.
I'm not sure why it's failing, since gcc is able to detect the type. I tried doing stuff from this post and playing around with it for a while but I keep running into a wall. MCVE available, or you can try it on coliru here:
#include <vector>
using namespace std;
template <typename T, template <typename> typename Container>
struct SomeClass {
SomeClass(const Container<T>& c) {
}
};
template <typename T, template <typename> typename C>
inline auto make_some_class(const C<T>& container) {
return SomeClass<T, C>(container);
}
int main() {
vector<int> ints;
auto stuff = make_some_class(ints);
}
main.cpp:19:18: error: no matching function for call to 'make_some_class'
auto stuff = make_some_class(ints); ^~~~~~~~~~~~~~~
main.cpp:12:13: note: candidate template ignored: substitution failure [with T = int]: template template argument has different template parameters than its corresponding template template parameter
inline auto make_some_class(const C<T>& container) { ^
1 error generated.
Suggestion: try with
#include <vector>
template <template <typename...> typename Container, typename ... Ts>
struct SomeClass {
SomeClass(const Container<Ts...>& c) {
}
};
template <template <typename...> typename C, typename ... Ts>
inline auto make_some_class(const C<Ts...>& container) {
return SomeClass<C, Ts...>(container);
}
int main() {
std::vector<int> ints;
auto stuff = make_some_class(ints);
}
I mean... I suppose the problem is that std::vector
isn't a container that receive one type template parameter; it's a container that receive two type template parameter (the second one with a default type: std::allocator<T>
where T
is the first one).
So the suggestion is: make SomeClass
more flexible and able to receive a container with an variadic list of template types of arguments
template <typename...> typename Container
and the corresponding list of template types
typename ... Ts
If you want a variadic list of arguments (Ts...
) you need it in last position so you have to switch the position of Container
and T
(now Ts...
): before Container
and after the variadic list Ts...
template <template <typename...> typename Container, typename ... Ts>
struct SomeClass {
SomeClass(const Container<Ts...>& c) {
}
};
Not strictly required but, for uniformity, I suggest to rewrite make_some_class()
in the same way (and, obviously, pass C
before Ts...
in the template parameters list).
template <template <typename...> typename C, typename ... Ts>
inline auto make_some_class(const C<Ts...>& container) {
return SomeClass<C, Ts...>(container);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With