Bon j'ai laissé tombé, je ne parviens pas à faire un code qui compile avec mingw-W64 il n'arrive pas à déduire les types lorsque j'utilise la méta fonction dans le main. Je voulais tenter de le faire parce que le fichier mp.h ne compile pas avec visual studio 2019 et je voulais voir si ça plantait aussi avec visual studio, au pire je peux essayer mais sans l'implémentation pour les placeholders c'est à dire sans le fichier mp.h.
Pourrais tu m'expliquer ce que tu souhaite faire avec le code
template <typename A>
requires std::derived_from<std::is_same<C, A>, std::true_type>
static constexpr std::true_type c () {
return std::true_type();
}
Car, je suis peut-être un peu fatigué après ma journée chargée, mais, à moins que je ne me trompe, std::derived_from permet de vérifier si un type (une classe) donné(e) est dérivé(e) d'une autre.
Et donc, tu veux t'assurer -- si je comprend bien ce code -- que le résultat de std::is_sama<A, C> soit bien dérivé de std::true_type; ce qui ne pourrait a priori arriver que si A et C sont des types identiques.
Heuu... n'as tu pas l'impression de faire finalement bien compliqué pour pas grand chose???
Je sais pas moi, mais je verrais bien plutôt quelque chose comme
template <typename U, typename V>
concept IsSame = std::is_same<U, V>::value == true;
template <typename U, typename V>
template <typename C>
struct contains {
template <typename A>
requires IsSame
static constexpr std::true_type c () {
return std::true_type();
}
template <typename A>
requires !IsSame
static constexpr std::false_type c () {
return std::false_type();
}
/* ... */
(le tout sans tenir compte du fait que tu chrerches peut-être les problèmes à renvoyer spécifiquement true_type et false_type ici )
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Ok mais c'est pas ça le problème je pense et puis, de toute façon je n'ai plus le temps pour implémenter ça, il faut que j'avance sur mon projet de jeux, sinon, je ne sortirai jamais la bêta.
J'ai tenté de compiler ce code mais il le compilateur ne peut pas déduire le type et j'ai d'autre erreurs (expression cannot be used as a function) que je ne comprend pas.
template<class T>
struct is_placeholder
: std::false_type
{};
template<std::size_t I, class T>
struct is_placeholder<ph<I, T>>
: std::true_type
{};
template <template <class...> class L, class A, class... Args>
struct push_front {
using type = L<A, Args...>;
};
template<class T, template<class> class Pred, template <class...> class R>
struct append_if {
template <typename A, class D, class... xs, class = typename std::enable_if<Pred<A>::value>::type>
static constexpr auto get() -> decltype(push_front<R,A, xs...>::type()){
return push_front<R,A, xs...>::type();
}
template <typename A, class... xs>
static constexpr auto get() -> decltype(R<xs...>()) {
return R<xs...>();
}
template <size_t I=0, class... D,class...E, size_t... Ints, class = typename std::enable_if<I == std::tuple_size<T>()>>
static constexpr auto func(std::index_sequence<Ints...>) -> decltype(get<decltype(std::get<Ints>(T())())...>()) {
return get<decltype(std::get<Ints>(T())())...>();
}
template <size_t I=0, class... D, size_t... Ints, class = typename std::enable_if<I != 0 && I != std::tuple_size<T>()>>
static constexpr auto const func(std::index_sequence<Ints...>) -> decltype(get<decltype(std::get<Ints>(T())())...>()) {
return get<decltype(std::get<Ints>(T())())...>();
}
template <size_t I=0, size_t... Ints>
static constexpr auto func(std::index_sequence<Ints...>) -> decltype(func<I+1>(std::make_index_sequence<std::tuple_size<T>()-I>())) {
return func<I+1>(std::make_index_sequence<std::tuple_size<T>()-I>());
}
};
template<template <class> class Pred, typename T, template <class> class R>
struct copy_if {
using f = decltype(append_if<T, Pred, R>::template func(std::make_index_sequence<std::tuple_size<T>()-0>()));
};
int main(int argc, char* argv[])
{
using late_params_t
= copy_if<is_placeholder,std::tuple<int, ph<3, int>, ph<2, int>,ph<1, int>,ph<0, int>>, std::tuple>
::f;
std::cout<<typeid(late_params_t).name()<<std::endl;
return 0; }
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Maintenant il ne me reste plus qu'à faire la même chose pour, virer les placeholders qui sont identiques et les trier, c'est un bonne exercice pour manipuler les tuples!!!
EDIT 2 : j'ai trouvé l'erreur, ce code fonctionne!!!
template <size_t SIZE, typename T>
struct placeholder {
static size_t constexpr size = SIZE;
using size_type = size_t;
using type = T;
};
template<class T>
struct is_placeholder
: std::false_type
{};
template<std::size_t I, class T>
struct is_placeholder<placeholder<I, T>>
: std::true_type
{};
template<std::size_t N, typename Seq> struct offset_sequence;
template<std::size_t N, std::size_t... Ints>
struct offset_sequence<N, std::index_sequence<Ints...>>
{
using type = std::index_sequence<Ints + N...>;
};
template<std::size_t N, typename Seq>
using offset_sequence_t = typename offset_sequence<N, Seq>::type;
template <size_t O, size_t N, size_t... Ints>
std::index_sequence<Ints...> make_offset_sequence () {
return offset_sequence_t<O, std::make_index_sequence<N>>::type();
}
template<typename Seq1, typename Seq> struct cat_sequence;
template<std::size_t... Ints1, std::size_t... Ints2>
struct cat_sequence<std::index_sequence<Ints1...>,
std::index_sequence<Ints2...>>
{
using type = std::index_sequence<Ints1..., Ints2...>;
};
template<typename Seq1, typename Seq2>
using cat_sequence_t = typename cat_sequence<Seq1, Seq2>::type;
template<typename T, std::size_t... Ints>
auto select_tuple(std::index_sequence<Ints...>)
{
T tuple;
return std::tuple<T>();
}
template<std::size_t N, typename T>
auto remove_Nth()
{
constexpr auto size = std::tuple_size_v<T>;
using first = std::make_index_sequence<N>;
using rest = offset_sequence_t<N+1,
std::make_index_sequence<size-N-1>>;
using indices = cat_sequence_t<first, rest>;
return select_tuple<T>(indices{});
}
template<template<class> class Pred, template <class...> class R>
struct append_if {
template <size_t I, class T, class... D, class = typename std::enable_if<Pred<decltype(std::get<I>(T()))>::value>::type>
static constexpr auto get() /*-> decltype(push_front<R,A, xs...>::type())*/{
return T();
}
template <size_t I, class T, class = typename std::enable_if<!Pred<decltype(std::get<I>(T()))>::value>::type>
static constexpr auto get() /*-> decltype(R<xs...>())*/ {
return remove_Nth<I, T>();
}
template <size_t I=0, class T, class... D, class = typename std::enable_if<(I == std::tuple_size<T>())>::type>
static constexpr auto f() /*-> decltype(get<decltype(std::get<Ints>(T())())...>())*/ {
return get<I-1, T>();
}
template <size_t I=0, class T, class... D, class... E, class = typename std::enable_if<(I != 0 && I != std::tuple_size<T>())>::type>
static constexpr auto const f() /*-> decltype(get<decltype(std::get<Ints>(T())())...>())*/ {
return get<I-1, T>();
}
template <size_t I=0, class T, class... D, class...E, class... F, class = typename std::enable_if<(I == 0)>::type>
static constexpr auto f() /*-> decltype(f<I+1>(std::make_index_sequence<std::tuple_size<T>()-I>()))*/ {
return f<I+1, T>();
}
};
template<template <class> class Pred, typename T, template <class> class R>
struct copy_if {
using f = decltype(append_if<Pred, R>::template f<0, T>());
};
int main(int argc, char* argv[])
{
using late_params_t
= copy_if<is_placeholder,std::tuple<placeholder<3, int>, float, placeholder<2, int>, int, placeholder<1, int>, char, placeholder<0, int>>, std::tuple>::f;
std::cout<<typeid(late_params_t).name()<<std::endl;
return 0;
}
Résolu!
Bon c'est moins rapide avec l'instanciation mais le code est moins salle que le fichier .hpp donc moins susceptible de planter.
- Edité par OmbreNoire 11 juin 2021 à 16:41:02
Le compilateur ne peut pas déduire les types.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Discord NaN. Mon site.
Discord NaN. Mon site.
Si vous ne trouvez plus rien, cherchez autre chose.