Getting tuple value via variable

I'm trying to get a tuple's element via an integer variable. The problem is when I run this code I get 14 errors:

Error C2784 'const tuple_element<_Idx,std::pair<_Ty1,_Ty2>>::type &std::get(const std::pair<_Ty1,_Ty2> &) noexcept': could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'std::tuple<int,int,const char *,const char *,float>' tuple_nth_element

Error C2974 'std::get': invalid template argument for '_Ty', type expected tuple_nth_element

Error C2338 tuple_element index out of bounds

Those were a couple of the errors and they were all line 38.

My question is how come when I call function(std::get<INDEX>(tuple)) I get all of these errors? From what I understand INDEX is an integer constant via recursion and should work with std::get?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <tuple>
#include <functional>
using namespace std;


template<size_t INDEX = 0, typename FN, typename... args>
void indexInTuple(size_t index, FN function, std::tuple<args...>& tuple) {
	static_assert(INDEX < sizeof...(args), "TUPLE INDEX OUT OF BOUNDS" );
	if (index != INDEX) {
		indexInTuple<INDEX + 1, FN, args...>(index, function, tuple);
	}
	else {
		function(std::get<INDEX>(tuple));
	}
}

int main() {
	auto tup = make_tuple(0, 2, "hello world");

	int index = 1; // for example
	indexInTuple(index, [](auto value) {
		cout << value;
	}, tup);
	 
	cin.get();
	return 0;
}
Last edited on
The compiler will try to generate code that calls the 'function' parameter with each of the tuple's elements. This is necessary because which element is called depends on a run-time value.
Although you used a lambda with an auto parameter, the type of the parameter can be only one. If the tuple contains different types, the compiler will not be able to decide which one to use.

I think what you want could be done if you pass the "callback" as a class template parameter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename Callback, size_t INDEX = 0, typename... args>
void indexInTuple(size_t index, std::tuple<args...>& tuple) {
	static_assert(INDEX < sizeof...(args), "TUPLE INDEX OUT OF BOUNDS" );
	if (index != INDEX) {
		indexInTuple<Callback, INDEX + 1, args...>(index, tuple);
	}
	else {
		Callback()(std::get<INDEX>(tuple));
	}
}

class Sample{
    template <typename T>
    void operator()(const T &x){
        std::cout << x;
    }
};

//...

indexInTuple<Sample>(index, tup);
I tried doing that and it gave me the same errors?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template<typename Callback, size_t INDEX = 0, typename... args>
void indexInTuple(size_t index, std::tuple<args...>& tuple) {
	static_assert(INDEX < sizeof...(args), "ERROR INDEX OUT OF BOUNDS" );
	if (index != INDEX) {
		indexInTuple<Callback, INDEX + 1, args...>(index, tuple);
	}
	else {
		Callback()(std::get<INDEX>(tuple));
	}
}

class Call {
public:
	template<typename T>
	void operator()(const T &x) {
		std::cout << x;
	}
};

int main() {
	auto tup = make_tuple(0, 2, "hello world");

	int index = 1; // for example
	indexInTuple<Call>(index, tup);
	cin.get();
	return 0;
}
I don't think what you're trying to do is possible, think about it, you have a branch which depends on a variable, how is the compiler supposed to create this function
Topic archived. No new replies allowed.