重载本地lambda函数

时间:2017-04-10 08:26:37

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

我有一个函数,对于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);
}

可以这样做吗?还是我过度伸展?

2 个答案:

答案 0 :(得分:5)

不幸的是,无论是使用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

答案 1 :(得分: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并使用正常的函数重载。