未使用的模板类型定义的同时参数包扩展错误

时间:2017-05-03 01:37:42

标签: c++ clang c++14 variadic-templates

我遇到的问题是来自clang(c ++ 14)的以下警告:

  

包扩展包含参数包'v_seconds',它与外部参数包具有不同的长度(3对1)

以下示例代码中遇到此问题:

template<typename... v_firsts>
struct types_list {
    template<typename... v_seconds>
    using pairs_list = types_list<std::pair<v_firsts, v_seconds>...>;
};

using my_types_list = types_list<short, int, long>;

using my_pairs_list = my_types_list::pairs_list<short, int, long>; // GOOD

template<typename... v_pack>
using any_pairs_list = my_types_list::pairs_list<v_pack...>; // BAD

我如何解释错误是以某种方式遇到any_pairs_list的{​​{1}}长度为1的特化,然后自然会遇到错误。

然而,上面的代码是整个示例代码 - 我从不使用v_seconds的专业化。

所以,我必须得出结论,尽管仍然创造了专业化......

现在,通常的TMP分叉问题:

any_pairs_list

P.S。我已经使用Apple安装的Clang(v8.1.0)以及Visual Studio 2017 Clang扩展进行了测试。不幸的是我没有linux环境来测试...

2 个答案:

答案 0 :(得分:2)

我最好的猜测是,Clang使用某种类型的启发式方法来检查固有的不可实现的模板。也许它(虚假地)决定any_pairs_list中的别名有一个参数,因为它没有正确处理包扩展,然后用一些独特的合成类型代替它来测试它是否原则上可行。毕竟,如果您不使用包但只使用一个沼泽标准模板参数,则会收到完全相同的错误消息。

报告为#32905

答案 1 :(得分:0)

不是解决方案,而是解决方法。使pairs_list成为名为成员typedef的结构,例如type。由于这是有效的,我会说这是Clang中using别名模板中的一个错误。

#include <iostream>
#include <utility>

template<typename... v_firsts>
struct types_list {
    template<typename... v_seconds>
    struct pairs_list {
      typedef types_list<std::pair<v_firsts, v_seconds>...> type;
    };
};

using my_types_list = types_list<short, int, long>;

using my_pairs_list = my_types_list::pairs_list<short, int, long>::type;

template<typename... v_pack>
using any_pairs_list = typename my_types_list::pairs_list<v_pack...>::type;

// Let's see what has been deduced

template < typename T >
void show_signature() { std::cout << __PRETTY_FUNCTION__ << '\n'; }

int main() {
  show_signature<my_types_list>(); // T = types_list<short, int, long>

  show_signature<my_pairs_list>(); // T = types_list<std::pair<short, short>, std::pair<int, int>, std::pair<long, long> >

  show_signature<any_pairs_list<int,long,double>>(); // T = types_list<std::pair<short, int>, std::pair<int, long>, std::pair<long, double> >
}