C++ 模版歧义

C++ 模版歧义,c++,c++11,templates,variadic-templates,template-meta-programming,C++,C++11,Templates,Variadic Templates,Template Meta Programming,有人能解释一下为什么由于模棱两可而未能遵守以下规定吗 #include <tuple> template <typename, typename, int> struct foo; template <template <typename...> class P, typename... Ts, typename... Us, int I> struct foo<P<Ts...>, std::tuple<P<Us.

有人能解释一下为什么由于模棱两可而未能遵守以下规定吗

#include <tuple>

template <typename, typename, int> struct foo;

template <template <typename...> class P, typename... Ts, typename... Us, int I>
struct foo<P<Ts...>, std::tuple<P<Us...>>, I> : foo<P<Ts...>, std::tuple<P<Us...>>, I-1> {};

template <template <typename...> class P, typename... Ts, typename... Us>
struct foo<P<Ts...>, std::tuple<P<Us...>>, 0> {};

template <typename...> struct P;

int main() {
    foo<P<int, bool, char>, std::tuple<P<>>, 5> a;
}

但是,出于某种原因,将
std::tuple
替换为
p
再次解决了这个问题。

尝试切换专门化的顺序:在零版本之前,下一个是通用整数版本

template <typename, typename, int> struct foo;

template <template <typename...> class P, typename... Ts, typename... Us>
struct foo<P<Ts...>, std::tuple<P<Us...>>, 0> {};

template <template <typename...> class P, typename... Ts, typename... Us, int I>
struct foo<P<Ts...>, std::tuple<P<Us...>>, I> : foo<P<Ts...>, std::tuple<P<Us...>>, I-1> {};

相互依赖(继承)

实际上,在我最初的产品代码中。我确实尝试过改变专业的顺序,但模棱两可的地方仍然存在。在这里,我减少了很多代码,以便更清楚地显示问题。我没想到在减少代码量后,突然改变顺序会起作用。@prestokeys-你是用g++编译的吗?如果您尝试使用clang++,会出现相同的错误吗?也许您将代码过于简化了,而原始的产品代码更加复杂,并且存在真正的歧义。您应该生成一个最小(但不是最小)的示例,该示例给出了切换专门化时的错误。我在问题中添加了我的非简化代码。它显示了同样的模糊性,切换专门化的顺序并不能解决问题(使用GCC 7.2)。不过读起来有点难。但简化它可能会得到同样意想不到的解决办法。@prestokeys-我明白了;我的clang++编译没有问题,但我的g++也有同样的问题;在这种情况下,您可以解决更改顺序的问题,因为存在循环依赖关系。@max66您的意思是可以还是不能?现在的模糊性是什么?它应该做什么?@Richard Hodges根据索引所指示的大小对包进行分区
is…
我已经通过修改代码完成了它,但我正试图调查早些时候让我感到困惑的所谓模糊性。
template <typename, typename, int> struct foo;

template <template <typename...> class P, typename... Ts, typename... Us>
struct foo<P<Ts...>, std::tuple<P<Us...>>, 0> {};

template <template <typename...> class P, typename... Ts, typename... Us, int I>
struct foo<P<Ts...>, std::tuple<P<Us...>>, I> : foo<P<Ts...>, std::tuple<P<Us...>>, I-1> {};
tmp_002-11,14,gcc,clang.cpp:21:8: error: invalid use of incomplete type ‘struct foo<P<int, bool, char>, std::tuple<P<> >, 0>’
 struct foo<P<Ts...>, std::tuple<P<Us...>>, I> : foo<P<Ts...>, std::tuple<P<Us...>>, I-1> {};
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template <template <typename...> class P, typename First, typename... Rest,
          typename... Ts, typename... Packs, std::size_t I, std::size_t... Is>
struct foo<P<First, Rest...>, std::tuple<P<Ts...>, Packs...>, I, Is...> 
   : foo<P<Rest...>, std::tuple<P<Ts..., First>, Packs...>, I-1, Is...>
 { };

template <template <typename...> class P, typename First, typename... Rest,
          typename... Ts, typename... Packs, std::size_t I, std::size_t J,
          std::size_t... Is>
struct foo<P<First, Rest...>, std::tuple<P<Ts...>, Packs...>, 0, I, J, Is...>
   : foo<P<Rest...>, std::tuple<P<First>, Packs..., P<Ts...>>, I-1, J, Is...>
{ };