修复了第三方代码:“错误:名称空间“ std”中的“ enable_if”未命名模板类型”

时间:2019-07-17 10:57:51

标签: c++ c++11 templates

在尝试构建第三方应用程序时,我发现它的依赖项(https://github.com/genome/joinx)不能与较新的编译器一起干净地编译。在整理它的过程中(多年以来,这些代码看起来都没有得到维护),我陷入了无法完全弄清楚的编译器错误。

问题出在此文件中:


#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;
    }
};

我的编译器发出错误消息:

/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
      |                                             ^

我不熟悉std::enable_if,并且先前在SO上进行的搜索均未提供与我的问题类似的解决方案。错误的确切原因是什么,所以我可以从那里开始进行修复?

1 个答案:

答案 0 :(得分:5)

为了将来帮助您“找到鱼”而不是给鱼:

error: ‘enable_if’ in namespace ‘std’ does not name a template type意味着在使用时,enable_if可能不为编译器所知。

搜索“ std :: enable_if”将最终使您转到此链接 https://en.cppreference.com/w/cpp/types/enable_if

您会注意到第Defined in header <type_traits>行。

这导致出现“是否包含此标头?”的问题。