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

Код ниже является фрагментом кода, над которым я работаю.В идеале пользователь библиотеки мог бы частично указать тип Fixed, предполагая, что он хочет использовать одинаковое целое число и точность в своем коде (значения FixedBase сопоставимы только в том случае, если они имеют одинаковую основу value_t).

Удивительно, но это не компилируется.Инстанцирование в main выбирает первый шаблон и затем завершается неудачей, потому что 11 не является типом ... несмотря на наличие допустимой специализации.

#include <cstdint>

/******** Library code *********/

template<typename value_t, std::size_t MAX_PREC>
class FixedBase {};

template<typename value_t, std::size_t MAX_PREC, int L, int R>
class Fixed : public FixedBase<value_t, MAX_PREC> {};

/********* User code **********/

// User specialization
template<int L, int R>
class Fixed<int64_t, 64, L, R> {};


int main(void) {

    Fixed<11, -3> a;

    return 0;
}

Основной вопрос заключается в том, почему он выбираетпервая специализация и провал, а не выбрать действительную вторую специализацию?Как заставить компилятор выбрать правильный?

Вторичный вопрос: есть ли лучший способ частично указать параметры шаблона?Я думаю, что может быть какой-то особый синтаксис using, с которым я не знаком и не нашел его во время поиска в Google.

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Когда вы добавляете частичную специализацию, например

template<int L, int R>
class Fixed<int64_t, 64, L, R> {};

Вы не создали шаблон для Fixed, который бы позволял вам указывать L и R, как вы делаете в Fixed<11, -3> a;.Что вы сделали, так это сказали компилятору, что если он видит

Fixed<int64_t, 64, some_int, some_other_int>

, то он должен использовать специализацию, поскольку совпадают первые два параметра.

Короче говоря: вы всегда должны указыватьвсе основные элементы шаблона.

0 голосов
/ 25 октября 2018

Вы неправильно поняли, как работает специализация, специализация не меняет список параметров шаблона.

В этом случае вы можете использовать псевдоним:

template<int L, int R>
using my_type = Fixed<int64_t, 64, L, R>;

int main(void) {

    my_type<11, -3> a;

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