C ++ 17类模板部分演绎

时间:2017-01-24 16:40:59

标签: c++ templates c++17

我对Template argument deduction for class templates提案的理解是在演绎上下文中同化模板函数和模板类的行为。但我认为我误解了一些事情。

如果我们有这个模板对象:

template <std::size_t S, typename T>
struct test
{
    static constexpr auto size = S;
    using type_t = T;

    test(type_t (&input)[size]) : data(input) {}
    type_t (&data)[size]{};
};

我倾向于使用辅助函数作为语法糖来创建test个对象:

template <std::size_t S, typename T>
test<S, T> helper(T (&input)[S]) { return input; }

可以使用如下所示:

int main()
{
    int buffer[5];

    auto a = helper<5, int>(buffer); // No deduction
    auto b = helper<5>(buffer);      // Type deduced
    auto c = helper(buffer);         // Type and size deduced

    std::cout << a.size << b.size << c.size;

    return 0;
}

上面的代码按预期输出555。我在Wandbox中尝试使用较新的编译器设置 1

int main()
{
    int buffer[5];

    test<5, int> a(buffer); // No deduction: Ok.
    test<5> b(buffer);      // Type deduced: FAILS.
    test c(buffer);         // Type and size deduced: Ok.

    std::cout << a.size << b.size << c.size;

    return 0;
}

看起来类模板的模板参数推导只能推导出所有参数,我期待两种行为(辅助函数和类模板)都是一样的,我误解了什么?

1 Wandbox中可用的最后一个编译器是 gcc HEAD 7.0.1 201701 clang HEAD 5.0.0(主干)

2 个答案:

答案 0 :(得分:18)

来自Botond Ballo的优秀trip report

  

最初提出的功能包括部分扣除的规定,您可以明确指定一些模板参数,并将剩下的部分推断出来,但这可以解释为在某些情况下它可能非常混乱:< / p>

// Would have deduced tuple<int, string, float>,
// but tuple<int> is a well-formed type in and of itself!
tuple<int> t(42, "waldo", 2.0f);

答案 1 :(得分:14)

这里似乎有矛盾。看一下P0091R3,似乎很明显允许部分指定参数:

  

我们建议在两个上下文中允许模板名称引用类模板作为简单类型说明符或部分提供显式模板参数

但同一提案中的实际标准措辞并未提供处理“部分提供的显式模板参数”的方法。 template-name作为简单类型说明符不允许有模板参数。

因此,遵循规范本身,编译器的行为似乎是正确的。