C++ 标准::获取<variable>失败
C++ std::get<variable> fails
如何使用 std :: get&lt;> 使用变量将变量置于元组中?我有以下代码:
#include <iostream>
#include <tuple>
using namespace std;
int main() {
tuple<int, int> data(5, 10);
for (int i=0; i<2; i++) {
cout << "#" << i+1 << ":" << get<i>(data) << endl;
}
return 0;
}
,并且由于以下编译器错误而失败:
prog.cpp: In function 'int main()':
prog.cpp:10:39: error: the value of 'i' is not usable in a constant expression
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:9:11: note: 'int i' is not const
for (int i=0; i<2; i++) {
^
prog.cpp:10:46: error: no matching function for call to
'get(std::tuple<int, int>&)'
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:10:46: note: candidates are:
In file included from /usr/include/c++/4.9/tuple:38:0,
from prog.cpp:2:
/usr/include/c++/4.9/utility:143:5: note: template<unsigned int _Int,
class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int,
std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)
get(std::pair<_Tp1, _Tp2>& __in) noexcept
^
/usr/include/c++/4.9/utility:143:5: note: template argument
deduction/substitution failed:
prog.cpp:10:46: error: the value of 'i' is not usable in a constant
expression
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:9:11: note: 'int i' is not const
for (int i=0; i<2; i++) {
^
prog.cpp:10:46: note: in template argument for type 'unsigned int'
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
In file included from /usr/include/c++/4.9/tuple:38:0,
from prog.cpp:2:
/usr/include/c++/4.9/utility:148:5: note: template<unsigned int _Int,
class _Tp1, class _Tp2> constexpr typename std::tuple_element<_Int,
std::pair<_Tp1, _Tp2> >::type&& std::get(std::pair<_Tp1, _Tp2>&&)
get(std::pair<_Tp1, _Tp2>&& __in) noexcept
^
/usr/include/c++/4.9/utility:148:5: note: template argument
deduction/substitution failed:
prog.cpp:10:46: error: the value of 'i' is not usable in a constant
expression
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:9:11: note: 'int i' is not const
for (int i=0; i<2; i++) {
^
prog.cpp:10:46: note: in template argument for type 'unsigned int'
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
In file included from /usr/include/c++/4.9/tuple:38:0,
from prog.cpp:2:
/usr/include/c++/4.9/utility:153:5: note: template<unsigned int _Int,
class _Tp1, class _Tp2> constexpr const typename
std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const
std::pair<_Tp1, _Tp2>&)
get(const std::pair<_Tp1, _Tp2>& __in) noexcept
^
/usr/include/c++/4.9/utility:153:5: note: template argument
deduction/substitution failed:
prog.cpp:10:46: error: the value of 'i' is not usable in a constant
expression
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
prog.cpp:9:11: note: 'int i' is not const
for (int i=0; i<2; i++) {
^
prog.cpp:10:46: note: in template argument for type 'unsigned int'
cout << "#" << i+1 << ":" << get<i>(data) << endl;
^
In file included from /usr/include/c++/4.9/tuple:38:0,
from prog.cpp:2:
/usr/include/c++/4.9/utility:162:5: note: template<class _Tp, class
_Up> constexpr _Tp& std::get(std::pair<_T1, _T2>&)
get(pair<_Tp, _Up>& __p) noexcept
我实际上截断了编译器错误消息,因为我认为它不会添加到超出点。有什么想法如何使该工作?
编辑:
只是为了澄清,使用array
类型并不是真正的选择。我必须使用tuple
,因为它是第三方库中API的返回类型。上面的示例只是为了使其易于理解。
如何使用变量使用std :: get&lt;>?
将变量索引到元组中
您不这样做,std::get<>
参数值必须在编译时间中知道。
任何想法如何使该工作?
是的,使用适当的类型:
int main() {
std::array<int, 2> data{ 5, 10 };
for (int i=0; i<2; i++) {
cout << "#" << i+1 << ":" << data[i] << endl;
}
return 0;
}
任何想法如何使该工作?
选项1
使用编译时常数访问std::tuple
。
cout << "#" << 1 << ":" << get<0>(data) << endl;
cout << "#" << 2 << ":" << get<1>(data) << endl;
选项2
使用可以在运行时使用索引访问元素的容器类型。
std::vector<int> data{5, 10};
或
std::array<int, 2> data{5, 10};
您应该采用的可能答案是仅使用数组,向量或其他类型的索引容器。
如果元组元素不是均匀类型,并且实际上您确实需要答案,则有点复杂。这是因为需要在编译时知道类型。因此,在您认为可以进行std::cout << get_from_tuple(a_tuple, index)
的地方,这不能像您想象的那样轻松地工作,因为在编译时选择了用于将对象发送到标准输出流的operator<<
过载。显然,这意味着该索引也必须在编译时知道 - 否则我们将不知道元组元素的类型。
但是,可以构建一个模板函数,实际上可以准确地实现此行为。最终结果是一条有条件的树,能够处理元组中的每个元素,但是我们邀请编译器来帮助我们建造条件树。
我将在这里构建的功能,给定元组,索引和函子将调用函数,转发该特定的元组项目,然后将返回true。如果索引不超出范围,则将返回false。
如果无法使用元组中的每个元素来调用函子,则模板函数将无法实例化。
最终解决方案看起来像这样:
#include <tuple>
#include <type_traits>
namespace detail {
template <std::size_t I>
struct size_wrapper { };
template <typename V, typename Tup, std::size_t I>
bool visit_tuple_index_impl(Tup && t, std::size_t index, V && visitor, size_wrapper<I>)
{
if (index == I - 1) {
visitor(std::get<I - 1>(std::forward<Tup>(t)));
return true;
}
return visit_tuple_index_impl(std::forward<Tup>(t), index, visitor, size_wrapper<I - 1>());
}
template <typename V, typename Tup>
bool visit_tuple_index_impl(Tup &&, std::size_t, V &&, size_wrapper<0>)
{
return false;
}
}
template <typename V, typename Tup>
bool visit_tuple_index(Tup && t, std::size_t index, V && visitor)
{
return detail::visit_tuple_index_impl(
std::forward<Tup>(t),
index,
std::forward<V>(visitor),
detail::size_wrapper<std::tuple_size<typename std::decay<Tup>::type>::value>()
);
}
#include <utility>
template<std::size_t...Is>
auto index_over( std::index_sequence<Is...> ) {
return [](auto&& f)->decltype(auto){
return decltype(f)(f)( std::integral_constant<std::size_t, Is>{}... );
};
}
template<std::size_t N>
auto index_upto( std::integral_constant<std::size_t, N> ={} ) {
return index_over( std::make_index_sequence<N>{} );
}
template<class F>
auto foreacher( F&& f ) {
return [f=std::forward<F>(f)](auto&&...args)mutable {
(void(), ..., void(f(decltype(args)(args))));
};
}
template<std::size_t N>
auto count_upto( std::integral_constant<std::size_t, N> ={} ) {
return [](auto&& f){
index_upto<N>()(foreacher(decltype(f)(f)));
};
}
您可以做:
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, int> data(5, 10);
count_upto<2>()([&](auto I){
std::cout << "#" << (I+1) << ":" << std::get<I>(data) << "n";
});
}
现场示例。
该解决方案中没有无界递归。它确实需要C 1Z-您可以用C 中的using unused=int[];
技巧替换foreacher
的主体。
- 如果没有malloc,链表实现将失败
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- gcc和c++17的过载解析失败
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 链接阶段在Ubuntu上失败,但在MacOS上失败
- 从父数组测试用例构造二叉树失败
- LibGit2 SSH身份验证失败
- 如何让LLDB在成功时退出,在失败时等待
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 生成MRPT库时cmake配置失败
- 为什么除非添加括号,否则构造函数上的模板替换会失败?
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败