if constexpr 用于可变长度元素 Get<>
if constexpr usage for variable length element Get<>
我正在尝试获取列表的第二个元素,但出现错误:
||=== Build: Debug in hellocpp17 (compiler: GNU GCC Compiler) ===|
/home/idf/Documents/c++/hellocpp17/main.cpp||In function ‘int main()’:|
/home/idf/Documents/c++/hellocpp17/main.cpp|67|error: no matching function for call to ‘Get<2>::Get(std::__cxx11::list<unsigned int>&)’|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get()|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate expects 0 arguments, 1 provided|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get(const Get<2>&)|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: no known conversion for argument 1 from ‘std::__cxx11::list<unsigned int>’ to ‘const Get<2>&’|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get(Get<2>&&)|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: no known conversion for argument 1 from ‘std::__cxx11::list<unsigned int>’ to ‘Get<2>&&’|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
节目:
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
template<unsigned n>
struct Get
{
template<class X, class...Xs>
constexpr auto operator()(X x, Xs...xs)
{
if constexpr(n > sizeof...(xs) )
{
return;
}
else if constexpr(n > 0)
{
return Get<n-1> {}(xs...);
}
else
{
return x;
}
}
};
int main()
{
list<unsigned> l = { 7, 5, 16, 8 };
unsigned l2 = Get<2>(l);
cout << l2 << endl;
return 0;
}
编辑 1
如果我实例化一个Get<2>
,编译器会报这个错误
unsigned l2 = Get<2>()(l);
/home/idf/Documents/c++/hellocpp17/main.cpp|67|error: void value not ignored as it ought to be|
你可以试试
unsigned l2 = Get<2>{}(7, 5, 16, 8);
您的代码中的第一个问题是
Get<2>(l);
不是对 Get<2>
的 operator()
的调用;它是一个带有 std::list
参数的 Get<2>
对象的构造。
不幸的是,没有 Get<2>
构造函数接收 std::list
。
你的代码中的第二个问题是,如果你像你想的那样调用 Get<2>
的 operator()
Get<2>{}(l)
其中 l
是一个 std::list
,你传递一个参数;不是参数的可变列表。并且您只能使用列表 l
运行 时间,而不是您想要的编译时间。
不幸的是,Get<2>{}(7, 5, 16, 8)
方式(接收可变参数列表的 operator()
)与包含列表的变量不兼容。
我的意思是......你不能做如下的事情
auto l = something{7, 5, 16, 8};
Get<2>{}(l);
但是,如果您修改 operator()
以接收 std::integer_sequence
,如下所示
template <template <typename X, X...> class C,
typename T, T I0, T ... Is>
constexpr auto operator() (C<T, I0, Is...> const &)
{
if constexpr (n > sizeof...(Is) )
return;
else if constexpr (n > 0)
return Get<n-1>{}(C<T, Is...>{});
else
return I0;
}
你可以像下面这样传递一个l
变量
auto l { std::integer_sequence<int, 7, 5, 16, 8>{} };
unsigned l2 = Get<2>{}(l);
我正在尝试获取列表的第二个元素,但出现错误:
||=== Build: Debug in hellocpp17 (compiler: GNU GCC Compiler) ===|
/home/idf/Documents/c++/hellocpp17/main.cpp||In function ‘int main()’:|
/home/idf/Documents/c++/hellocpp17/main.cpp|67|error: no matching function for call to ‘Get<2>::Get(std::__cxx11::list<unsigned int>&)’|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get()|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate expects 0 arguments, 1 provided|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get(const Get<2>&)|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: no known conversion for argument 1 from ‘std::__cxx11::list<unsigned int>’ to ‘const Get<2>&’|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: candidate: constexpr Get<2>::Get(Get<2>&&)|
/home/idf/Documents/c++/hellocpp17/main.cpp|40|note: no known conversion for argument 1 from ‘std::__cxx11::list<unsigned int>’ to ‘Get<2>&&’|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
节目:
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
template<unsigned n>
struct Get
{
template<class X, class...Xs>
constexpr auto operator()(X x, Xs...xs)
{
if constexpr(n > sizeof...(xs) )
{
return;
}
else if constexpr(n > 0)
{
return Get<n-1> {}(xs...);
}
else
{
return x;
}
}
};
int main()
{
list<unsigned> l = { 7, 5, 16, 8 };
unsigned l2 = Get<2>(l);
cout << l2 << endl;
return 0;
}
编辑 1
如果我实例化一个Get<2>
,编译器会报这个错误
unsigned l2 = Get<2>()(l);
/home/idf/Documents/c++/hellocpp17/main.cpp|67|error: void value not ignored as it ought to be|
你可以试试
unsigned l2 = Get<2>{}(7, 5, 16, 8);
您的代码中的第一个问题是
Get<2>(l);
不是对 Get<2>
的 operator()
的调用;它是一个带有 std::list
参数的 Get<2>
对象的构造。
不幸的是,没有 Get<2>
构造函数接收 std::list
。
你的代码中的第二个问题是,如果你像你想的那样调用 Get<2>
的 operator()
Get<2>{}(l)
其中 l
是一个 std::list
,你传递一个参数;不是参数的可变列表。并且您只能使用列表 l
运行 时间,而不是您想要的编译时间。
不幸的是,Get<2>{}(7, 5, 16, 8)
方式(接收可变参数列表的 operator()
)与包含列表的变量不兼容。
我的意思是......你不能做如下的事情
auto l = something{7, 5, 16, 8};
Get<2>{}(l);
但是,如果您修改 operator()
以接收 std::integer_sequence
,如下所示
template <template <typename X, X...> class C,
typename T, T I0, T ... Is>
constexpr auto operator() (C<T, I0, Is...> const &)
{
if constexpr (n > sizeof...(Is) )
return;
else if constexpr (n > 0)
return Get<n-1>{}(C<T, Is...>{});
else
return I0;
}
你可以像下面这样传递一个l
变量
auto l { std::integer_sequence<int, 7, 5, 16, 8>{} };
unsigned l2 = Get<2>{}(l);