首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么重载成员函数访问元组和递归累加结果失败?

为什么重载成员函数访问元组和递归累加结果失败?
EN

Stack Overflow用户
提问于 2014-08-14 14:20:36
回答 1查看 284关注 0票数 2

我想访问元组成员,并在下一步累加结果。但不工作,而且它看起来像是出界访问(无效使用不完整的类型struct std::tuple_element<0u, std::tuple<> >)

代码语言:javascript
复制
#include <iostream>
#include <tuple>

template<typename...ARGS>
struct NextTest
{
    std::tuple<ARGS...> data;
    template<std::size_t I,bool=I<sizeof...(ARGS)>
    struct Dispatch{};
    template<std::size_t I,typename T>
    T next3(T t,Dispatch<I,false>)const
    {
        return t;
    }
    template<std::size_t I,typename T>
    auto next3(T t,Dispatch<I,true>)const->decltype(this->next3<I+1>(std::get<I>(data),Dispatch<I+1>{}))
    {

        return this->next3<I+1>(std::get<I>(data),Dispatch<I+1>{});
    }
    template<std::size_t I,typename T>
    auto next3(T t)const->decltype(this->next3<I>(t,Dispatch<I>{}))
    {
        return this->next3<I>(t,Dispatch<I>{});
    }
    template<std::size_t I,typename T,typename std::enable_if<(I>=sizeof...(ARGS))>::type* =nullptr>
    T next(T t)const
    {
        return t;
    }
    template<std::size_t I,typename T,typename std::enable_if<(I<sizeof...(ARGS))>::type* =nullptr>
    auto next(T t)const->decltype(this->next<I+1>(std::get<I>(data)))
    {

        return this->next<I+1>(std::get<I>(data));
    }
    template<std::size_t I,typename std::enable_if<(I>=sizeof...(ARGS))>::type* =nullptr>
    void next2()const
    {
        std::cout<<"end!";
    }
    template<std::size_t I,typename std::enable_if<(I<sizeof...(ARGS))>::type* =nullptr>
    void next2()const
    {
        std::cout<<"in seq ";
        next2<I+1>();
    }

};
void testexpr1()
{
    NextTest<int> nt;
    nt.next<0>( 1);//fail
nt.next3<0>( 1);//fail
nt.next2<0>();//pass!
}

明朝gcc 4.8.1为什么出错?我该怎么做呢?

**update1:**结果如下:

代码语言:javascript
复制
...\include\c++\tuple||In instantiation of 'struct std::tuple_element<1u, std::tuple<int> >':|
...\include\c++\tuple|771|  required by substitution of 'template<unsigned int __i, class ... _Elements> constexpr typename std::__add_r_ref<typename std::tuple_element<__i, std::tuple<_Elements ...> >::type>::type std::get(std::tuple<_Elements ...>&&) [with unsigned int __i = 1u; _Elements = {int}]'|
...\test.cpp|83|  required by substitution of 'template<unsigned int I, class T> decltype (this->.next1<(I + 1)>(get<I>(this->.data))) NextTest<ARGS>::next1(T&, typename std::enable_if<(I < sizeof (ARGS ...))>::type*) [with unsigned int I = I; T = T; ARGS = {int}] [with unsigned int I = 1u; T = <missing>]'|
...\test.cpp|83|  required by substitution of 'template<unsigned int I, class T> decltype (this->.next1<(I + 1)>(get<I>(this->.data))) NextTest<ARGS>::next1(T&, typename std::enable_if<(I < sizeof (ARGS ...))>::type*) [with unsigned int I = I; T = T; ARGS = {int}] [with unsigned int I = 0u; T = int]'|
...\test.cpp|104|required from here|
...\include\c++\tuple|680|error: invalid use of incomplete type 'struct std::tuple_element<0u, std::tuple<> >'|
...\include\c++\utility|84|error: declaration of 'struct std::tuple_element<0u, std::tuple<> >'|
EN

回答 1

Stack Overflow用户

发布于 2014-10-08 01:53:00

代码中似乎有两个错误:

  • One正如@Nawaz提到的那样->是在decltype部分访问成员函数和成员变量所必需的(至少在gcc 4.7.2中是这样)。
  • 第二个是访问元组元素的off-by-one error (参见enable_if元函数调用中将'I‘更改为'I+1’的位置和Dispatch结构中的默认参数)。

修复了这两个问题后,代码在gcc 4.7.2上编译得很好。

下面是固定的代码:

代码语言:javascript
复制
#include <iostream>
#include <tuple>

template<typename...ARGS>
struct NextTest
{
    std::tuple<ARGS...> data;

    template<std::size_t I,bool=(I+1)<sizeof...(ARGS)>
    struct Dispatch{};

    template<std::size_t I,typename T>
    T next3(T t,Dispatch<I,false>)const
    {
        return t;
    }
    template<std::size_t I,typename T>
    auto next3(T t,Dispatch<I,true>)const->decltype(this->next3<I+1>(std::get<I>(this->data),Dispatch<I+1>{}))
    {
        return this->next3<I+1>(std::get<I>(data),Dispatch<I+1>{});
    }
    template<std::size_t I,typename T>
    auto next3(T t)const->decltype(this->next3<I>(t,Dispatch<I>{}))
    {
        return this->next3<I>(t,Dispatch<I>{});
    }

    template<std::size_t I,typename T,typename std::enable_if<((I+1)>=sizeof... (ARGS))>::type* =nullptr>
    T next(T t)const
    {
        return t;
    }
    template<std::size_t I,typename T,typename std::enable_if<((I+1)<sizeof...(ARGS))>::type* =nullptr>
    auto next(T t)const->decltype(this->next<I+1>(std::get<I>(this->data)))
    {
        return this->next<I+1>(std::get<I>(data));
    }

    template<std::size_t I,typename std::enable_if<((I+1)>=sizeof...(ARGS))>::type* =nullptr>
    void next2()const
    {
        std::cout<<"end!";
    }
    template<std::size_t I,typename std::enable_if<((I+1)<sizeof...(ARGS))>::type* =nullptr>
    void next2()const
    {
        std::cout<<"in seq ";
        next2<I+1>();
    }
};

void testexpr1()
{
    NextTest<int> nt;
    nt.next<0>( 1);//pass
    nt.next3<0>( 1);//pass
    nt.next2<0>();//pass!
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25301302

复制
相关文章

相似问题

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