Reputation: 10828
I currently have the following problem. I have the following class:
class Container
{
public:
explicit Container(Resolver& r);
~Container();
template <typename Interface>
Interface& Create();
size_t GetNumberOfManagedObjects();
private:
template <typename Interface>
Interface& InternalCreate();
Resolver& m_resolver;
std::vector<std::pair<std::function<void(void*)>,intptr_t>> m_deleter;
std::unordered_map<std::string,intptr_t> m_singletons;
};
now I need a version of InternalCreate
that is used when the template parameter 'Interface' is of type std::vector, and I need a version that is used otherwise. Is that possible (e.g. using std::enable_if)? From what I've read, partial specialization is not possible in this case but I can't fully specify the types inside the vector. Can someone help?
Regards Tobias
Upvotes: 1
Views: 73
Reputation: 119457
Using a helper function, you can take advantage of template parameter deduction. Here's an example which you can adapt to your program:
#include <iostream>
#include <vector>
class Foo {
public:
template <typename T>
T Create() {
return helper(static_cast<T*>(nullptr));
}
private:
template <typename T>
static T helper(T*) {
std::cout << "Using generic helper\n";
return {};
}
template <typename T>
static std::vector<T> helper(std::vector<T>*) {
std::cout << "Using specialized helper\n";
return {};
}
};
int main() {
Foo f;
f.Create<int>();
f.Create<int*>();
f.Create<std::vector<int>>();
f.Create<std::vector<int>*>();
f.Create<std::vector<std::vector<int>>>();
return 0;
}
Output:
Using generic helper
Using generic helper
Using specialized helper
Using generic helper
Using specialized helper
Upvotes: 0
Reputation: 96845
SFINAE seems to be the correct solution here. You can create a trait which returns std::true_type
when the type it receives is a vector:
template<typename Container>
struct is_vector : std::false_type { };
template<typename T>
struct is_vector<std::vector<T>> : std::true_type { };
Now you can enable an overload for a vector like this:
template <typename Interface>
Interface& InternalCreate(
typename std::enable_if<is_vector<Interface>{}>::type* ptr = nullptr);
template <typename Interface>
Interface& InternalCreate(
typename std::enable_if<!is_vector<Interface>{}>::type* ptr = nullptr);
Upvotes: 1