【问题标题】:Comparing 2 values using template metaprogramming C++使用模板元编程 C++ 比较 2 个值
【发布时间】:2018-11-23 20:34:52
【问题描述】:

我希望有一个默认函数作为“谓词”模板,以防用户不提供。到目前为止,我一直在做类似的事情:

template<typename T>
struct simple_compare{
    bool operator()(T const& a, T const& b){
        return a > b;
    }
};

template<typename T, typename Predicate=simple_compare<T> >
bool compare(T a, T b, Predicate pred) {
    return pred(a, b);
}

这可以在 C++ 中使用模板元编程来完成,而不是使用带有重载 () 运算符的结构吗?

【问题讨论】:

  • 你也可以有一个模板特化,有/没有用户定义的谓词。我认为不需要“元编程”。
  • @Klaus,在这种情况下,我认为不对,你不能部分专门化模板函数,直到像 c++20 之类的东西。
  • 我已经考虑过使用专门化,但我希望可以使用模板来完成编译时执行。但如果不能那样做,我还不如接受专业化的简单解决方案。
  • 我仍然认为您的解决方案运行良好。如果你需要一个默认的自定义比较函数,你应该把它写在某个地方。元编程不会为你编写代码。
  • C++11、C++14 还是 C++17?

标签: c++ templates template-meta-programming


【解决方案1】:

这里不需要模板元编程。您可以简单地使用 Davide Spataro 的答案中所示的重载来提供不采用谓词的版本,而只需使用默认谓词调用完整版本。或者你可以只为你的谓词使用一个默认参数:

template <typename T, typename Predicate = simple_compare<T>>
bool compare(T a, T b, Predicate pred = {}) {
    return pred(a, b);
}

如果您只想要一个调用 > 运算符的通用仿函数,那么您也可以将 operator () 设为模板而不是仿函数类型本身,然后从调用中推断出要比较的确切类型:

struct simple_compare {
    template <typename A, typename B>
    bool operator()(A const& a, B const& b) const {
        return a > b;
    }
};

template <typename T, typename Predicate = simple_compare>
bool compare(T a, T b, Predicate pred = {}) {
    return pred(a, b);
}

此外,标准库已经提供standard functors 用于调用各种运算符。因此,您可以在示例中使用std::greater&lt;T&gt;std::greater&lt;void&gt;,而不是自己滚动。此外,我认为没有真正需要要求您的参数是可复制的并且是相同类型的:

template <typename A, typename B, typename Predicate = std::greater<void>>
bool compare(A const& a, B const& b, Predicate pred = {}) {
    return pred(a, b);
}

【讨论】:

  • 不是必须模板化的structsimple_compare吗?
  • @JeJo 我在原始问题中看不到任何要求 simple_compare 必须是模板!?
  • 我很好奇这条线template &lt;typename T, typename Predicate = simple_compare&lt;T&gt;&gt;,而你提供的是非模板struct simple_compare
  • @MichaelKenzel std::greater 实际上是我的想法。谢谢。
  • @JeJo 这一行只是为了展示带有原始函数和比较器模板的默认参数方法。仅将 operator () 转换为模板而不是 simple_compare 是一个独立的建议。我编辑了我的答案,希望能澄清......
【解决方案2】:

你不需要花哨的模板元编程东西。 只需创建模板函数的两个版本。没有自定义谓词的那个只会执行默认谓词。

以下内容应该有效:

auto default_pred = [](const auto a, const auto b) {return a > b;};
auto custom_pred  = [](const auto a, const auto b) {return a < b;};


template<typename T, typename Fn >
bool compare2(T a, T b, Fn pred) {
    return pred(a, b);
}

template<typename T >
bool compare2(T a, T b) {
    return default_pred (a, b);
}

int main(){
    cout<<compare2(2, 4)<<endl;
    cout<<compare2(10.2d, 4.5d, custom_pred)<<endl;
   return 0;
}

【讨论】:

  • 为什么要进行代码复制说如果 tmrw 您想在比较 a 和 b 之前对其进行一些规范化,那么您必须在 compare2 的两个重载中都这样做
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
相关资源
最近更新 更多