Boost 如何使用同一函数处理不同的迭代器值类型

Boost 如何使用同一函数处理不同的迭代器值类型,boost,c++11,Boost,C++11,有关以下代码: template < class _InIt, class _Ty, class _Fn2 > inline _Ty accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func) { // return sum of _Val and all in [_First, _Last), using _Func for (; _First

有关以下代码:

template < class _InIt,
           class _Ty,
           class _Fn2 > inline
_Ty accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    // return sum of _Val and all in [_First, _Last), using _Func
    for (; _First != _Last; ++_First)
    {
        if (is_class<std::iterator_traits<_InIt>::value_type>::value)
            _Val = _Func(_Val, (*_First)());
        else
            _Val = _Func(_Val, *_First);//This line doesn't work...
    }
    return (_Val);
}
template内联
_Ty累加采样器(_InIt_First,_InIt_Last,_Ty_Val,_Fn2_Func)
{
//使用_Func返回[_First,_Last]中的_Val和all之和
对于(;_First!=_Last;++_First)
{
if(is_class::value)
_Val=_Func(_Val,(*_First)();
其他的
_Val=\u Func(\u Val,*\u First);//此行不起作用。。。
}
返回(_Val);
}
我希望代码既能用于指向双精度的
\u InIt
,又能用于指向类。 如果指向一个类,我将使用
(*_First)(
来获取数据(假设该类具有返回
double
的运算符()),否则我只需使用
*_First
来获取数据


有没有任何方法可以使用
boost::Is_class
或其他任何方法来实现这一点?

我认为这不是一个好主意。我更愿意编写两个不同的函数来处理两种不同的类型,例如:

// Also, note, your function is very similar to 
// std::accumulate from numeric header

std::vector<Foo> v1{3.14159, 1.77245385};
std::accumulate
(
    v1.begin(), v1.end(), 0.,
    [] (double i, const Foo& f) { return i + f(); }
);

std::vector<double> v2{3.14159, 1.77245385};
std::accumulate(v2.begin(), v2.end(), 0.);
#include <type_traits>
#include <iterator>

// Compiler will choose this one when the value_type is a class
template < class _InIt,
           class _Ty,
           class _Fn2
>
typename std::enable_if<
    std::is_class<
        typename std::iterator_traits<_InIt>::value_type
    >::value,
    _Ty
>::type
accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    // return sum of _Val and all in [_First, _Last), using _Func
    for (; _First != _Last; ++_First) {
        _Val = _Func(_Val, (*_First)());
    }
    return (_Val);
}

// Compiler will choose this one when the value_type is not a class
template < class _InIt,
           class _Ty,
           class _Fn2
>
typename std::enable_if<
    !std::is_class<
        typename std::iterator_traits<_InIt>::value_type
    >::value,
    _Ty
>::type
accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    // return sum of _Val and all in [_First, _Last), using _Func
    for (; _First != _Last; ++_First) {
        _Val = _Func(_Val, *_First);
    }
    return (_Val);
}
//另外,请注意,您的函数与
//std::从数字标题累加
std::向量v1{3.14159,1.77245385};
累积
(
v1.begin(),v1.end(),0。,
[](双i,常数Foo&f){return i+f();}
);
std::矢量v2{3.14159,1.77245385};
std::累加(v2.begin(),v2.end(),0);
但如果您不想这样做,我建议您编写一个函数包装器:

namespace detail
{

template <class F, class V, class T>
auto function_wrapper(F&& f, V&& v, T&& t)
    ->  typename std::enable_if
        <
            std::is_class<typename std::remove_reference<T>::type>::value,
            typename std::remove_reference<V>::type
        >::type
{
    return std::forward<F>(f)(std::forward<V>(v), std::forward<T>(t)());
}

template <class F, class V, class T>
auto function_wrapper(F&& f, V&& v, T&& t)
    ->  typename std::enable_if
        <
            !std::is_class<typename std::remove_reference<T>::type>::value,
            typename std::remove_reference<V>::type
        >::type
{
    return std::forward<F>(f)(std::forward<V>(v), std::forward<T>(t));
}

} // namespace detail

template < class _InIt,
           class _Ty,
           class _Fn2 > inline
_Ty accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    for (; _First != _Last; ++_First)
        _Val = detail::function_wrapper(_Func, _Val, *_First);
    return (_Val);
}

class Foo
{
public:
    Foo(double d): _d(d)
    {

    }

    double operator() () const
    {
        return _d;
    }

private:
    double _d;
};


int main()
{
    auto f = [] (double a, double b) { return a + b; };

    std::vector<Foo> v1{3.14159, 1.77245385};
    std::cout << accumulateSimplePtr(v1.begin(), v1.end(), 0., f) << std::endl;

    std::vector<double> v2{3.14159, 1.77245385};
    std::cout << accumulateSimplePtr(v2.begin(), v2.end(), 0., f) << std::endl;

    return 0;
}
名称空间详细信息
{
模板
自动函数包装器(F&&F、V&&V、T&&T)
->typename std::启用\u如果
<
std::is_class::value,
typename std::remove_reference::type
>::类型
{
返回std::forward(f)(std::forward(v),std::forward(t)();
}
模板
自动函数包装器(F&&F、V&&V、T&&T)
->typename std::启用\u如果
<
!std::is_class::value,
typename std::remove_reference::type
>::类型
{
返回std::forward(f)(std::forward(v),std::forward(t));
}
}//名称空间详细信息
模板内联
_Ty累加采样器(_InIt_First,_InIt_Last,_Ty_Val,_Fn2_Func)
{
对于(;_First!=_Last;++_First)
_Val=detail::函数包装器(_Func,_Val,*\u First);
返回(_Val);
}
福班
{
公众:
Foo(双d):\u d(d)
{
}
双运算符()()常量
{
返回d;
}
私人:
双d;
};
int main()
{
自动f=[](双a,双b){返回a+b;};
std::向量v1{3.14159,1.77245385};

std::cout如果应用于 模板函数,用于指示编译器实例化 不同的函数取决于值类型是类还是类 不是这样的:

// Also, note, your function is very similar to 
// std::accumulate from numeric header

std::vector<Foo> v1{3.14159, 1.77245385};
std::accumulate
(
    v1.begin(), v1.end(), 0.,
    [] (double i, const Foo& f) { return i + f(); }
);

std::vector<double> v2{3.14159, 1.77245385};
std::accumulate(v2.begin(), v2.end(), 0.);
#include <type_traits>
#include <iterator>

// Compiler will choose this one when the value_type is a class
template < class _InIt,
           class _Ty,
           class _Fn2
>
typename std::enable_if<
    std::is_class<
        typename std::iterator_traits<_InIt>::value_type
    >::value,
    _Ty
>::type
accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    // return sum of _Val and all in [_First, _Last), using _Func
    for (; _First != _Last; ++_First) {
        _Val = _Func(_Val, (*_First)());
    }
    return (_Val);
}

// Compiler will choose this one when the value_type is not a class
template < class _InIt,
           class _Ty,
           class _Fn2
>
typename std::enable_if<
    !std::is_class<
        typename std::iterator_traits<_InIt>::value_type
    >::value,
    _Ty
>::type
accumulateSimplePtr(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
{
    // return sum of _Val and all in [_First, _Last), using _Func
    for (; _First != _Last; ++_First) {
        _Val = _Func(_Val, *_First);
    }
    return (_Val);
}
#包括
#包括
//当值类型为类时,编译器将选择此类型
模板
typename std::启用\u如果<
std::这是一个类吗<
typename std::迭代器特征::值类型
>::价值,
_泰
>::类型
累加采样器(_InIt_First,_InIt_Last,_Ty_Val,_Fn2_Func)
{
//使用_Func返回[_First,_Last]中的_Val和all之和
对于(;_First!=_Last;++_First){
_Val=_Func(_Val,(*_First)();
}
返回(_Val);
}
//当值_类型不是类时,编译器将选择此类型
模板
typename std::启用\u如果<
!std::这是你的职业吗<
typename std::迭代器特征::值类型
>::价值,
_泰
>::类型
累加采样器(_InIt_First,_InIt_Last,_Ty_Val,_Fn2_Func)
{
//使用_Func返回[_First,_Last]中的_Val和all之和
对于(;_First!=_Last;++_First){
_Val=_Func(_Val,*_First);
}
返回(_Val);
}
阅读有关
std::如果

您尝试这样做的方式不起作用,因为它需要 编译器编译*is_a_类”和is_非_a_类分支 即使它们不能同时编译。
std::enable_if
导致 只有正确的函数才能被编译

请注意,不应使用以下划线开头的标识符 和大写字母作为所有此类标识符保留给编译器和
它的库。请参阅。

感谢您的解决方案