编译器选择无效的模板专业化并失败

时间:2018-10-25 15:24:15

标签: c++ templates

下面的代码是我正在研究的代码库的摘录。理想情况下,库用户可以部分指定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语法,在谷歌搜索时找不到。

2 个答案:

答案 0 :(得分:4)

您误解了专业化的工作原理,专业化并没有改变模板参数列表。

在这种情况下,您可以使用别名:

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

int main(void) {

    my_type<11, -3> a;

    return 0;
}

答案 1 :(得分:3)

当您添加部分专业化内容时

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

您还没有为Fixed创建模板,只能像在L中那样指定RFixed<11, -3> a;。您所做的就是告诉编译器是否看到

Fixed<int64_t, 64, some_int, some_other_int>

然后应该使用专业化,因为它们的前两个参数匹配。

长话短说:您始终必须指定所有主要模板成员。