It's my first post on Stackoverflow.
I'm currently hurting a problem. I have a code working outside of a class(or struct) but when I put into a class it's failed.
My objective is to be able to get a reference of a tuple element using a predicate.
So I found here https://www.fluentcpp.com/2019/03/08/stl-algorithms-on-tuples/ an example of find_if for tuple.
It works great.
So I get an index of tuple where my element is.
Now it's easy i can use std::get to get my reference.
My sample worked in a main.cpp So i decided to clean it by moving this into my class to get an api of the form :
constexpr T& MyStruct::get(const char* name).
But now my code is not compiling. The commented code is not compiling :
#include <tuple>
#include <iostream>
/******************************************************************************************************/
//Helper to find tuple element index
template <class Tuple, class F, std::size_t... I>
constexpr F for_each_impl(Tuple&& t, F&& f, std::index_sequence<I...>)
{
return (void)std::initializer_list<int>{(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))), 0)...}, f;
}
template <class Tuple, class F>
constexpr F for_each(Tuple&& t, F&& f)
{
return for_each_impl(std::forward<Tuple>(t), std::forward<F>(f),
std::make_index_sequence<std::tuple_size<std::remove_reference_t<Tuple>>::value>{});
}
template<typename Tuple, typename Predicate>
constexpr size_t find_if(Tuple&& tuple, Predicate pred)
{
size_t index = std::tuple_size<std::remove_reference_t<Tuple>>::value;
size_t currentIndex = 0;
bool found = false;
for_each(tuple, [&](auto&& value)
{
if (!found && pred(value))
{
index = currentIndex;
found = true;
}
++currentIndex;
});
return index;
}
/***********************************************************************************************/
template <typename T>
struct LabelType {
constexpr LabelType(const char* label, T val) : _label(label), _value(val) {}
const char* _label;
T _value;
};
template <typename ...Args>
struct LabelList {
constexpr LabelList(Args... args) : _tuple(std::forward<Args>(args)...) {}
//constexpr auto& get(const char* name) const {
// constexpr auto index = find_if(_tuple, [&](const auto& type) {
// return type._label == name;
// });
// return std::get<std::tuple_element_t<index, std::tuple<Args...>>>(_tuple);
//}
std::tuple<Args...> _tuple;
};
int main() {
constexpr auto list = LabelList{
LabelType{"int label", 123},
LabelType{"string label", "hello world"},
LabelType{"float label", 3.14f},
LabelType{"bool label", false},
};
constexpr auto index = find_if(list._tuple, [&]( const auto& type) {
return type._label == "string label";
});
constexpr auto& string_ref = std::get<std::tuple_element_t<index, decltype(list._tuple)>>(list._tuple);
std::cout << string_ref._label << " - " << string_ref._value;
//constexpr auto& string_ref2 = list.get("string label");
//std::cout << string_ref2._label << " - " << string_ref2._value;
}
If someone have any idea to fix it or an other way to do what I want?