【问题标题】:Overload local lambda function重载本地 lambda 函数
【发布时间】:2017-04-10 08:26:36
【问题描述】:

我有一个与doubleint 输入几乎相同的功能。因此,我重载了这两种类型的函数。不幸的是,在核心,doubleint 变体之间存在差异。目前,我为此依赖于重载的“核心”功能。为了提高可读性,我希望将重载(非常短)的核心函数作为函数本身的一部分,例如使用 lambda 函数。

下面这个例子总结了我目前的布局(当然真正的代码要多一些)。

#include <iostream>
#include <cstdlib>

double func_core ( double a, double b ) {
  return a*b;
}

int func_core ( int a, int b ) {
  if ( a==b )
    return 1.;
  else
    return 0.;
}

template <class T> T func ( T a, T b ) {
  return func_core(a,b);
}

int main ( void ) {
  std::cout << func(10 ,20 ) << std::endl;
  std::cout << func(10.,20.) << std::endl;
  return 0;
}

由于本示例之外的原因,我使用 C++14(与此一致,我使用 clang++ -std=c++14 example.cpp 编译了此示例)。

现在,我想摆脱核心功能(在此示例中为func_core),因为它降低了我的代码的可读性。理想情况下,我想使用在函数本身内重载的lambda 函数。我在下面的示例中总结了我的想法(这不起作用)。

template <class T> T func ( T a, T b ) {
  if ( sizeof(T)==sizeof(int) )
    auto func_core = [](int a,int b){ if (a==b) return 1.; else return 0.; };
  else if ( sizeof(T)==sizeof(double) )
    auto func_core = [](double a,double b){ return a*b; };
  else
    throw std::runtime_error("Overload type not allowed");

  return func_core(a,b);
}

这可以吗?还是我过度拉伸了?

【问题讨论】:

  • 如果sizeof(T) == sizeof(int)T 不是不是 int(例如可能是float)怎么办?可读性和可维护性如何?您能否详细说明为什么要删除func_core 重载?将解决的实际问题是什么?
  • @Someprogrammerdude。公平点,我添加了一个例外。至于我为什么想要这个,我有许多这些“核心”功能一次属于一个功能(因为它们相似,但略有不同)。提议的方法将避免这些“核心”功能是可重用实体的建议。

标签: c++ c++11 lambda c++14


【解决方案1】:

不幸的是,无论是使用 C++11 还是 C++14,您都需要使用 SFINAE 之类的野兽或重载决议来完成您想要的。

但是,在 C++17 中,您可以使用 constexpr if 并将所有所需的功能合并到一个函数模板中:

template<typename T>
 T func (T const &a, T const &b) {
  if constexpr(std::is_integral<T>::value)
    return (a == b)? 1 : 0;
  else
    return a * b;
}

Live Demo

【讨论】:

  • 感谢这个好建议。在评估我所说的func_core 后,当我不直接return 时,您是否也有建议?例如。 func_corefor 循环中添加一些变量。 (事后看来,我应该在示例中包含此内容,但现在我会破坏此提要。)
  • 这在 C++11/14 中也应该能很好地工作,如果在那里省略 constexpr:std::is_integral&lt;T&gt;::value 仍然是一个编译时间常数,编译器应该优化掉 if 和未使用的路径.
【解决方案2】:

您可以使用type traits

template <class T> T func ( T a, T b ) {
    if (std::is_integral<T>::value)
        if (a==b) return 1;
        else return 0;
    else if (std::is_floating_point<T>::value)
        return a*b;
    else
        throw std::runtime_error("Overload type not allowed");
}

无论如何,我认为最好的方法是避免使用 lambdas 并使用正常的函数重载。

【讨论】:

  • 这还没有达到我的目标:变量func_core 在评估之前就超出了范围。
  • @TomdeGeus 是的,也许你应该内联函数。其实是一样的,我来编辑一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-12
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多