2017-04-10 66 views
2

我有一个功能,它几乎相同的doubleint输入。因此我已经重载了这两种类型的函数。不幸的是,在核心上,doubleint变体之间存在差异。目前,我依赖于一个超载的'核心'功能。为了提高可读性,我希望将超载(非常短)的核心功能作为函数本身的一部分,例如使用lambda函数。过载本地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); 
} 

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

+0

那么如果'sizeof(T)== sizeof(int)'但T'是* not *'int'(例如它可能是'float')呢?可读性和可维护性如何?你可以详细说明*为什么*你想删除'func_core'重载?什么是将解决的实际问题? –

+0

@Someprogrammerdude。公平点,我增加了一个例外。至于我为什么要这样做,我有许多属于同一功能的“核心”功能(因为它们是相似的,但略有不同)。所提出的方法将避免暗示这些“核心”功能是可重复使用的实体。 –

+1

我建议你使用http://en.cppreference.com/w/cpp/language/partial_specialization – tty6

回答

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

+0

感谢这个好建议。在评估我所说的“func_core”后,如果我没有直接'返回',你是否也有一个建议?例如。 'func_core'在'for'循环中增加了一些变量。 (在后面我应该包括这个例子,但现在我会毁了这个饲料。) –

+0

这应该在C++ 11/14中也能很好地工作,如果在那里忽略constexpr:'std :: is_integral :: value'仍然是一个编译时间常量,编译器应该优化掉if和未使用的路径。 – Aconcagua

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并使用正常的函数重载。

+0

这还没有达到我的目的:在评估之前,变量func_core超出了范围。 –

+0

@TomdeGeus真的,也许你应该内联函数。这实际上是一样的,我会编辑 – amchacon