Reputation: 5188
Is there a way to workaround the limitations of the standard when it comes to use template parameters in template arguments in partial specialization? The code that I'd like to make it work is this:
template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0>
class a{};
template<typename L>
class a<L, sizeof(L)-1>{};
Upvotes: 2
Views: 1520
Reputation: 18905
I dont know if this is what you mean. This is how you can select a different implementation if the second template arguemnt matches the size of first template argument - 1.
template<typename L, size_t offset>
class aImplMatch
{ // choose this if offset == sizeof(L) - 1
L v;
};
template<typename L, size_t offset>
class aImpl
{
L v;
char off[offset];
};
template<typename L, size_t offset, size_t i>
struct SelectImpl{};
template<typename L, size_t offset>
struct SelectImpl<L, offset, 0> { typedef aImplMatch<L, offset> Result; };
template<typename L, size_t offset>
struct SelectImpl<L, offset, 1> { typedef aImpl<L, offset> Result; };
template<typename L, size_t offset>
class a
{
enum {I = offset == sizeof(offset) - 1 ? 0 : 1 };
typedef typename SelectImpl<L, offset, I>::Result Impl;
Impl impl;
};
Maybe it could be done better / easier, this was my first thought...
Upvotes: 2
Reputation: 523174
Since it's C++11, you could simply use static_assert
for the generic condition. For the sizeof(L)-1
thing, you need to use the enable_if
trick since it requires something to be specialized. Example:
#include <cstdlib>
#include <type_traits>
#include <cstdio>
template <typename L, size_t offset, typename = void>
class a
{
static_assert(offset < sizeof(L), "something's wrong");
public:
void f()
{
printf("generic\n");
}
};
template <typename L, size_t offset>
class a<L, offset, typename std::enable_if<offset == sizeof(L)-1>::type>
{
// note: the static_assert is *not* inherited here.
public:
void f()
{
printf("specialized\n");
}
};
int main()
{
static_assert(sizeof(int) == 4, "oops");
a<int, 3> x;
a<int, 2> y;
x.f();
y.f();
return 0;
}
Demo: http://ideone.com/D2cs5
Upvotes: 5