Having to use C++14 I'd like to use std::enable_if to make a function only being available given certain constraints. I do so using or_<>
taken from the libc header type_traits
instead of std::disjunction
(no C++17 available in my environment) in order to move the constraint logic into a separate construct.
However, I seem to be missing something, because I can't manage to get it to compile.
My code:
#include <type_traits>
#include <iostream>
#include <vector>
#include <list>
template <typename T>
struct IsVector : public std::false_type {};
template <typename T>
struct IsVector<std::vector<T>> : public std::true_type {};
template <typename T>
struct IsList : public std::false_type {};
template <typename T>
struct IsList<std::list<T>> : public std::true_type {};
// taken from libc type_traits
template <bool, typename, typename>
struct conditional;
template <typename...>
struct or_;
template <>
struct or_<> : public std::false_type {};
template <typename _B1>
struct or_<_B1> : public _B1 {};
template <typename _B1, typename _B2>
struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};
template <typename _B1, typename _B2, typename _B3, typename... _Bn>
struct or_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, _B1, or_<_B2, _B3, _Bn...>>::type {};
// ---
template <typename T>
struct IsVectorOrList : public or_<IsVector<T>, IsList<T>>::type {};
template <typename T>
typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type
// replacing with this line does not work
//typename std::enable_if<IsVectorOrList<T>::value, void>::type
foo(const T& list)
{
for (const auto& item : list)
{
std::cout << item << std::endl;
}
}
int main()
{
foo(std::vector<int>{17, 42});
foo(std::list<float>{1.0, 2.71, 3.14});
}
When using typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type
as constraint it works fine. If I use typename std::enable_if<IsVectorOrList<T>::value>::type
the compiler complains:
traits.cpp:32:8: error: invalid use of incomplete type ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
32 | struct or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type {};
| ^~~~~~~~~~~~~
traits.cpp:20:8: note: declaration of ‘struct conditional<true, IsVector<std::vector<int> >, IsList<std::vector<int> > >’
20 | struct conditional;
| ^~~~~~~~~~~
How do I make it work?
Aucun commentaire:
Enregistrer un commentaire