首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模版歧义

模版歧义
EN

Stack Overflow用户
提问于 2017-10-13 22:03:49
回答 1查看 90关注 0票数 0

有谁能解释一下为什么以下内容由于模棱两可而不符合?

代码语言:javascript
复制
#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% )。我上面的简化代码显然可以通过切换专门化的顺序来解决。下面,切换订单不起作用。

代码语言:javascript
复制
#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解决了这个问题(再次),原因是。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-13 22:17:56

尝试切换专门化的顺序:在零版本之前,接下来是泛型整数版本。

代码语言:javascript
复制
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)给出了一些错误,第二个错误是

代码语言:javascript
复制
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 bat的专门化--这种专门化是“不完全的”。

如果您先将版本与I == 0放在一起,则不再是不完整的(从其他专门化的角度来看)。

-编辑--

对于“未简化的代码”,问题似乎是相同的(仅针对g++),但在本例中,您无法解决更改专门化顺序的问题,因为以下两个专门化

代码语言:javascript
复制
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...>
{ };

相互依赖(继承)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46738603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档