Bonjour !
Je cherche à faire un explode sur un string, et que chaque partie coupée du string, soit castée vers un type voulu, (si aucun type n'est donné, le type retourné sera un simple std::string.
Donc, pour commencer, il faut connaitre le nombre de cast voulus, et les types voulus (en variadic)
Du coup, si l'utilisateur donne NCasts = 0, on ne fera aucun cast et la fonction retournera un std::tuple< std::string ... >
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 template<int NCasts, typename... Casts> static const std::tuple<int, Casts...> explode(const std::string& str, const char separator) { return explode_impl<std::string, NCasts, Casts...>::call(str, separator); }
Ce qui donne, version 1 : avec cast, version 2: NCasts = 0:
Ensuite, il manque le découpage et le cast... pour le cas général, et le cas std::string (Au cas ou l'utilisateur demande par exemple std::tuple<int, string, long>)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
29
30
31
32
33 // v1 template<typename String, int NCasts, typename... Casts> struct explode_impl { static const std::tuple<int, Casts...> call(const String& str, const char separator) { std::string buffer; std::tuple<decltype(NCasts), Casts...> result; decltype(NCasts) i = 0; while(++i < NCasts) result = std::tuple_cat(result, explode_call_impl<String, decltype(nth_argument<const_cast<decltype(i)>(i), Casts...>::value)>::call(buffer, str, separator)); std::get<0>(result) = NCasts; return result; } }; // v2 template<typename String, typename... Casts> struct explode_impl<String, 0, Casts...> { static const std::tuple<int, Casts...> call(const String& str, const char separator) { std::string buffer; std::tuple<int, Casts...> result = std::make_tuple<int, Casts...>(0); for(int& i = std::get<0>(result); ; ++i) { if(!std::getline(str, buffer, separator)) break; result = std::tuple_cat(result, buffer); } return result; } };
Donc...
Il vous faudra également nth_argument, alors le voici:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 template<typename String, typename Cast> struct explode_call_impl { static const Cast call(std::string& buffer, const String& str, const char separator) { if(!std::getline(str, buffer, separator)) return; std::istringstream temp_ss(buffer); Cast casted; temp_ss >> casted; return casted; } }; template<typename String> struct explode_call_impl<String, std::string> { static const std::string call(std::string& buffer, const String& str, const char separator) { if(!std::getline(str, buffer, separator)) return; return buffer; } };
De loin ca à l'air bien, mais le compilo n'est pas d'accord!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 template<int N, typename T, T... Args> struct nth_argument { static constexpr T values[sizeof...(Args)] = {Args...}; static const T value = values[N]; }; template<int N, typename T, T... Args> constexpr T nth_argument<N, T, Args...>::values[sizeof...(Args)];
Quelqu'un saurait me dire ce qui cloche ?/media/data/dev/projects/test/test_type/../../Tools/tools.h: In instantiation of ‘const std::tuple<int, Casts ...> tools::explode(const string&, char) [with int NCasts = 0; Casts = {}; std::string = std::basic_string<char>]’:
/media/data/dev/projects/test/test_type/main.cpp:9:83: required from here
/media/data/dev/projects/test/test_type/../../Tools/tools.h:52:84: error: no matching function for call to ‘variadic::explode_impl<std::basic_string<char>, 0>::explode_impl(const string&, const char&)’
return variadic::explode_impl<std::string, NCasts, Casts...>(str, separator);
^
/media/data/dev/projects/test/test_type/../../Tools/tools.h:52:84: note: candidates are:
In file included from /media/data/dev/projects/test/test_type/../../Tools/tools.h:7:0,
from /media/data/dev/projects/test/test_type/main.cpp:2:
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: constexpr variadic::explode_impl<std::basic_string<char>, 0>::explode_impl()
struct explode_impl<String, 0, Casts...>
^
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: candidate expects 0 arguments, 2 provided
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: constexpr variadic::explode_impl<std::basic_string<char>, 0>::explode_impl(const variadic::explode_impl<std::basic_string<char>, 0>&)
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: candidate expects 1 argument, 2 provided
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: constexpr variadic::explode_impl<std::basic_string<char>, 0>::explode_impl(variadic::explode_impl<std::basic_string<char>, 0>&&)
/media/data/dev/projects/test/test_type/../../Tools/variadic.h:97:12: note: candidate expects 1 argument, 2 provided
Merci d'avance
nico
Partager