重载成员函数访问元组和递归累加结果失败的原因
why overload member function access tuple and recurse accumulate result fail?
我想访问元组成员并累积结果next和next。但不工作,它看起来是越界访问(无效使用不完整类型struct std::tuple_element<0u, std::tuple<> >
)
#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!
}
mingw GCC 4.8.1为什么出错?我该怎么办呢?
**update1:**this complie out:
...includec++tuple||In instantiation of 'struct std::tuple_element<1u, std::tuple<int> >':|
...includec++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|
...includec++tuple|680|error: invalid use of incomplete type 'struct std::tuple_element<0u, std::tuple<> >'|
...includec++utility|84|error: declaration of 'struct std::tuple_element<0u, std::tuple<> >'|
代码中似乎有两个错误:
- 一个是@Nawaz提到的,在decltype部分中需要->来访问成员函数和成员变量(至少在gcc 4.7.2中)。
- 第二个是访问元组元素时的一个off- 1错误(参见在enable_if元函数调用和Dispatch结构中的默认参数中'I'被更改为'I+1')。
修复了这两个问题后,代码在gcc 4.7.2上可以很好地编译。
下面是固定的代码:#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!
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 如果没有malloc,链表实现将失败
- valgrind-hellgrind与泄漏检查的结果不同
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 用C++20 fmt限制结果的总大小
- 如何返回一个类的两个对象相加的结果
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 结果失败或多个参数无效
- 查找函数在失败结果中应该返回什么
- Netbeans 7.4 C++简单的 hello world 错误构建失败尝试了 Google 搜索结果前 2 页上的
- CImg:图像二值化结果失败
- 重载成员函数访问元组和递归累加结果失败的原因
- 通过usb从控制器获取结果失败