The next level of template programming (beyond very simple use) has eluded me for months as I work on a specific project I've been working on. I've tried scores of methods, cutting and pasting from StackOverflow as well as trying to understand and roll my own, with no breakthroughs. A few of the techniques I've tried hit a roadblock at SFINAE with std::enable_if<>
, so I've distilled the issue down and ask about that.
Let's start with a baseline template:
template<typename T>
struct foo
{
string bar(const T& val);
};
Then specialize it for a vector of ints:
template<>
struct foo<vector<int> >
{
string bar(vector<int> c);
};
This compiles and utilizes the correct templates from the type, as expected. But I need to be able to have more control over which templates are used.
The best I can understand from the C++ reference and numerous other sites, if I add std::enable_if<>
to the mix (utilizing the enable_if_t<>
alias), the following should give me the exact same behavior, replacing the std::enable_if_t<true, vector<int> >
with just vector<int>
:
template<>
struct foo<std::enable_if_t<true, vector<int> > >
{
string bar(vector<int> c);
};
And it works, compiling and running as expected.
However, if I instead use partial specialization, things work differently. Without std::enable_if<>
, this works as well:
template<typename T>
struct foo<vector<T> >
{
string bar(vector<T> c);
};
But adding in std::enable_if<true, vector<T> >
fails. I would expect it to replaced with vector<T>
, which worked above:
template<typename T>
struct foo<std::enable_if_t<true, vector<T> > >
{
string bar(vector<T> c);
};
But this gives me a compile time error:
test.cpp:48:8: error: template parameters not deducible in partial specialization:
463 | struct foo<std::enable_if_t<true, vector<T> > >
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:48:8: note: âTâ
I understand that this is partial specialization. But, so was the previous version, without the std::enable_if<>
. Obviously, there is something different, but debugging templates is pretty opaque, and no amount of googling has led me to a clue. So it's not clear to me what is different, or how to get the compiler to handle this the same as without std::enable_if<>
.
Please note that the end goal is to replace the vector
with templated types in other containers, and I will need to separate sequential and associative containers into different implementations. I really have tried a ton of combinations, including variadics and template template parameters. I can get many of them to work for multiple containers, but each has various issues as I think I'm getting to an answer. Conditional compilation like this (obviously with an enable/disable based on type_traits) seems like it might help with reaching a full solution in more than one of those cases.
Online version is here (just swap commenting of lines 47 & 48): http://coliru.stacked-crooked.com/a/d4892db81a4c9957
Any help appreciated.