аргумент шаблона, включающий параметры шаблона - PullRequest
2 голосов
/ 31 января 2012

Есть ли способ обойти ограничения стандарта, когда речь идет об использовании параметров шаблона в аргументах шаблона при частичной специализации? Код, который я хотел бы сделать так, чтобы он работал:

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>{};

Ответы [ 2 ]

4 голосов
/ 31 января 2012

Поскольку это C ++ 11, вы можете просто использовать static_assert для общего условия. Для вещи sizeof(L)-1 вам нужно использовать трюк enable_if, так как для этого требуется нечто особенное. Пример:

#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;
}

Демо: http://ideone.com/D2cs5

2 голосов
/ 31 января 2012

Я не знаю, если это то, что вы имеете в виду. Вот как вы можете выбрать другую реализацию, если второй аргумент шаблона соответствует размеру первого аргумента шаблона - 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;
};

Может быть, это можно сделать лучше / проще, это была моя первая мысль ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...