0

我想做一個簡單的函數 - 一對多變量一次模板,它工作得很好,但我只是覺得不夠滿足。這裏是工作代碼:模板元編程與經典名稱重載混合

#include <iostream> 

// generated for last (or the only) variable sent to apply_to_many template overload 
template<class Fun, class Type> 
void apply_to_many(Fun fun, Type& current) 
{ 
    current = fun(current); 
} 

// variadic template + variadic arguments, fun is applied to 
// current variable, and template is generated for the rest 
template<class Fun, class Type, class ...Types> 
void apply_to_many(Fun fun, Type& current, Types&... other_variables) 
{ 
    current = fun(current); 
    if(sizeof...(other_variables) > 0) 
     apply_to_many(fun, other_variables...); 
} 

// simple function returning square of value 
int square(int x) 
{ 
    return x*x; 
} 

int main() 
{ 
    // some ints 
    int a{3}, b{4}, c{5}, d{6}, e{7}; 

    std::cout << a << '\t' 
       << b << '\t' 
       << c << '\t' 
       << d << '\t' 
       << e << std::endl; 

    apply_to_many(square, a, b, c, d, e); 

    std::cout << a << '\t' 
       << b << '\t' 
       << c << '\t' 
       << d << '\t' 
       << e << std::endl; 
} 

輸出:

3  4  5  6  7 
9  16  25  36  49 

雖然a b c d e可以是不同的類型,如intdoublecomplex<float>,就是在這裏應用的功能僅適用於int S,所以int小號被平方像int s,float s被平方像int s,complex<float> es被平方像int s ...好吧,complex<float>只是無法轉換。重點是 - 使用爲這些類型提供的經典過載將會很不錯,如std::sqrtstd::pow。但顯然,我們無法將重載名稱傳遞給模板,而無需明確選擇一個過載。據我所知,我們不能發送模板函數作爲參數(這將是驚人的,但可能很棘手)。我會接受任何事情,甚至是宏觀的。

回答

4

您可以使用通用的拉姆達(C++ 14):

apply_to_many([](auto v) { return std::sqrt(v); }, a, b, c, d, e); 

Demo

在C++ 11,你要創建的仿函數的老路上:

struct Sqrt 
{ 
    template <typename T> 
    auto operator()(T value) const 
    -> decltype(std::sqrt(value)) 
    { 
     return std::sqrt(value); 
    } 
}; 

及更高版本

apply_to_many(Sqrt{}, a, b, c, d, e);