有人可以解释为什么以下因为含糊不清而无法遵守
#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
,则会消除歧义。如果我将P<Ts...>
或P<Us...>
替换为名为Pack
的简单类型,也会将其删除。我正在使用GCC 7.2。当然,foo<P<int, bool, char>, std::tuple<P<>>, 0>
会出现歧义。如果我从foo
定义中删除第一个模板,也会删除歧义。
这是我的非简化代码(好吧,减少了大约10%)。我上面简化的代码显然可以通过切换专业化的顺序来解决。下面,切换订单不起作用。
#include <tuple>
template <typename Pack, typename OutputPack, std::size_t...> struct foo;
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...> {};
template <template <typename...> class P, typename First, typename... Rest, typename... Ts, typename... Packs, std::size_t Last>
struct foo<P<First, Rest...>, std::tuple<P<Ts...>, Packs...>, 0, Last> {};
template <typename...> struct P;
int main() {
foo<P<int, bool, char, int, long, bool>, std::tuple<P<>>, 1,2,1> a;
}
但是,将std::tuple
替换为P
会因某种原因(再次)解决问题。
答案 0 :(得分:1)
尝试切换特化顺序:在零版本之前,接下来是通用整数版本。
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> {};
我的clang ++(3.8.1)编译您的原始代码没有问题,但我的g ++(6.3.0)给出了几个错误,第二个是
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> {};
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我不知道谁是对的:g ++或clang ++。
但是g ++抱怨通用整数特化调用(I==1
)与I == 0
的专门化使这个专业化“不完整”。
如果您首先放置I == 0
版本,则不再完整(从其他专业化的角度来看)。
- 编辑 -
关于你的“非简化代码”,问题看起来是一样的(仅适用于g ++)但是,在这种情况下,你无法解决改变专业化顺序的问题,因为以下两个专业化
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...>
{ };
相互依赖(继承)