Как я могу частично специализировать нетиповые параметры шаблона класса - PullRequest
0 голосов
/ 03 декабря 2018

Мой вопрос довольно простой.Я пытаюсь создать для себя экземпляр шаблона класса удобства, который делает что-то математически интуитивно понятным.Я хочу иметь возможность создавать экземпляр класса с именем Q<0,31>, создавая его как Q<31>.Согласно cppreference.com, это должно быть возможно :

template<class T> 
class A<int, T*, 5> {}; // #3: partial specialization where T1 is int, I is 5,
                        //     and T2 is a pointer

Но когда я пытаюсь это сделать:

template< unsigned integral, unsigned fractional >
class Q: public Signed<integral + fractional + 1u> {};

// There's a shorthand for Q notation where you don't specify the number of integer bits, and it's assumed to be 0
template< unsigned fractional > class  Q<0u, fractional>: public Signed<fractional + 1> {};

static_assert( std::is_same< Q<31>, Q<0,31> >::value, "Partial specialization should be equivalent to no integer component");

, тогда я получаю сообщение об ошибке: «Нет»передано достаточно аргументов шаблона

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Вы не можете достичь этого так, как хотите, потому что, как уже было сказано, нет и перегрузки, но это возможно с помощью шаблона псевдонима с частичной специализацией:

template<int, int B>
struct Q {};

template<int B>
using Q0 = Q<0,B>;

в вашем коде

static_assert( std::is_same< Q0<31>, Q<0,31> >::value, "Partial specialization should be equivalent to no integer component");

компилируется без ошибок

0 голосов
/ 03 декабря 2018

Специализации не являются перегрузками.Они соответствуют шаблону.

Нет способа "перегрузить" шаблон, как вы хотите, если не считать магических значений.

template< unsigned fractional >
class  Q<0u, fractional>

это просто шаблон соответствует.

Ваши аргументы всегда

template< unsigned integral, unsigned fractional >
class Q

, и ваша специализация совпадает, когда кто-то передает 0u для integral.Таким образом, он соответствует

Q<0u, fractional>

, он не соответствует

Q<fractional>

Теперь, как уже упоминалось, вы можете сделать это с помощью магических значений:

template< unsigned integral, unsigned fractional=-1 >
class Q
template< unsigned fractional >
class Q<fractional, -1>:Q<0u, fractional> {}

, но это также происходит, если кто-то передает -1 вручную.

В вы можете иметь пользовательские типы в качестве шаблонных параметров шаблонных типов,так что вы можете сделать что-то вроде:

template< unsigned A, optional<unsigned> B = {} >
class Q;

template< unsigned integral, unsigned fractional >
class Q< integral, optional<unsigned>(fractional) > // 2 arg case

template< unsigned fractional >
class Q< fractional, nullopt >:Q<0u, fractional> {}; // 1 arg case

, но это еще не здесь.

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