Reputation: 4933
While trying to build a third party application, I found that one of its dependencies (https://github.com/genome/joinx) would not compile cleanly with newer compilers. In the process of tidying it up (the code looks unmaintained since years), I got stuck with a compiler error I can't quite figure out.
The issue is in this file:
#pragma once
// Utilities for comparing things / establishing orderings.
#include <boost/utility/declval.hpp>
///////////////////////////////////////////////////////////////////////////
// Tags for use with enable_if
// Compare objects return an int <0, =0, or >0 to establish an ordering
// (cf. strcmp)
struct CompareBase {};
// ComparePred objects are predicates (e.g., less than)
// (cf. std::less)
struct ComparePredBase {};
template<typename Op>
struct DerefBinaryOp {
Op op;
explicit DerefBinaryOp(Op op = Op())
: op(op)
{}
template<typename ValueType>
auto operator()(ValueType const& x, ValueType const& y) -> decltype(op(*x, *y)) {
return op(*x, *y);
}
};
// Given a "Compare" function, convert it to a less than predicate.
template<
typename T
, typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
>
struct CompareToLessThan : ComparePredBase {
CompareToLessThan(T cmp = T())
: cmp(cmp)
{}
template<typename U>
bool operator()(U const& x, U const& y) const {
return cmp(x, y) < 0;
}
T cmp;
};
// Given a "Compare" function, convert it to a greater than predicate.
template<
typename T
, typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
>
struct CompareToGreaterThan : ComparePredBase {
CompareToGreaterThan(T cmp = T())
: cmp(cmp)
{}
template<typename U>
bool operator()(U const& x, U const& y) const {
return cmp(x, y) > 0;
}
T cmp;
};
// This is a helper class that defines relational operators
// (>, <, ==, !=, ...) for simple structs that define value_type
// and have a single member: value_type value;
template<typename T>
struct ValueBasedRelOps {
friend bool operator<(T const& lhs, T const& rhs) {
return lhs.value < rhs.value;
}
friend bool operator>(T const& lhs, T const& rhs) {
return lhs.value > rhs.value;
}
friend bool operator<=(T const& lhs, T const& rhs) {
return lhs.value <= rhs.value;
}
friend bool operator>=(T const& lhs, T const& rhs) {
return lhs.value >= rhs.value;
}
friend bool operator==(T const& lhs, T const& rhs) {
return lhs.value == rhs.value;
}
friend bool operator!=(T const& lhs, T const& rhs) {
return lhs.value != rhs.value;
}
};
And my compiler spews out errors:
/home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:34:36: error: ‘enable_if’ in namespace ‘std’ does not name a template type
34 | , typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
| ^~~~~~~~~
/home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:34:45: error: expected ‘>’ before ‘<’ token
34 | , typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
| ^
/home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:52:36: error: ‘enable_if’ in namespace ‘std’ does not name a template type
52 | , typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
| ^~~~~~~~~
/home/einar/Download/Sources/joinx/src/lib/common/RelOps.hpp:52:45: error: expected ‘>’ before ‘<’ token
52 | , typename = typename std::enable_if<std::is_base_of<CompareBase, T>::value>::type
| ^
I'm unfamiliar with std::enable_if
and the previous searches on SO did not yield a solution similar to my problem. What's the exact cause of the error, so I can start working from there to fix it?
Upvotes: 5
Views: 6757
Reputation: 6983
To help you "find the fish" in the future rather than be given a fish:
error: ‘enable_if’ in namespace ‘std’ does not name a template type
means that enable_if
more than likely is unknown to the compiler at that point of usage.
Searching for std::enable_if
will lead you eventually to this link:
https://en.cppreference.com/w/cpp/types/enable_if
You will note the line "Defined in header <type_traits>
".
This leads to the question "Has this header been included?".
Upvotes: 7