MSVC 2010的<functional>(嵌套绑定)问题</functional>

时间:2010-10-24 17:47:48

标签: c++ visual-studio-2010 gcc c++11 functional-programming

我有以下代码(对不起,我很抱歉):

double primeValue( const func1D &func,
                   const double lowerBound, const double upperBound,
                   const double pole )
{
    // check bounds
    if( lowerBound >= upperBound )
        throw runtime_error( "lowerBound must be smaller than upperBound!" );

    // C++0x way of writing: fullFunc(x) = func(x)/(x-a)
    func1D fullFunc =
            bind( divides<double>(),              // division of
                  bind(func, _1),                 // f(x), with _1 = x
                  bind(minus<double>(), _1, pole) ); // by x-a, with _1 = x

    // pole not in domain
    if( pole<lowerBound || pole>upperBound)
    {
        cout << "Case 1" << endl;
        return integrateSimpson( fullFunc, 1000, lowerBound, upperBound );
    }
    // pole closer to upper bound
    else if( upperBound-pole < pole-lowerBound  )
    {
       cout << "Case 2" << endl;
       // C++0x way of writing g(x) := [f(x)-f(2a-x)]/(x-a)
       func1D specialFirstFunc =
                bind( std::divides<double>(),                               // division of
                      bind(minus<double>(),                                 // numerator:
                           bind(func, _1),                                  // f(x) minus
                           bind(func, bind(minus<double>(), 2.*pole, _1))), //f(2a-x)
                      bind(minus<double>(), _1, pole) );                    // denominator: x-a
        const double trickyPart = integrateSimpson( specialFirstFunc, 1000, pole+.000001, upperBound );

        const double normalPart = integrateSimpson( fullFunc, 1000, lowerBound, 2.*pole-upperBound );
        cout << "Tricky part: " << trickyPart << endl;
        cout << "Normal part: " << normalPart << endl;
        return trickyPart + normalPart;
    }
    else // pole closer to lower bound
    {
        cout << "Case 3" << endl;
        // C++0x way of writing g(x) := [f(x)-f(2a-x)]/(x-a)
        func1D specialFirstFunc =
                 bind( std::divides<double>(),                               // division of
                       bind(minus<double>(),                                 // numerator:
                            bind(func, _1),                                  // f(x) minus
                            bind(func, bind(minus<double>(), 2.*pole, _1))), //f(2a-x)
                       bind(minus<double>(), _1, pole) );                    // denominator: x-a
         const double trickyPart = integrateSimpson( specialFirstFunc, 1000, lowerBound, pole-.00001 );

         const double normalPart = integrateSimpson( fullFunc, 1000, 2.*pole-lowerBound, upperBound );
         cout << "Tricky part: " << trickyPart << endl;
         cout << "Normal part: " << normalPart << endl;
         return trickyPart + normalPart;
    }
}

它使用复杂分析的数学域中的主值概念,在包含奇点(极点)的实轴上集成函数。 bindfunction部分将原始函数f(x)修改为

  

(F(X)-f(2 *极-X))/(X-A)

它甚至为我的简单测试用例函数提供了正确的结果。如果需要,我可以提供其他详细信息:

typedef std::function<double (double)> func1D;
double integrateSimpson( func1D, const size_t nSteps, const double lowerBound, const double upperBound);

后者使用简单的Simpson集成规则进行集成。可以提供代码,但与手头的问题无关。

这适用于GCC 4.4+(使用4.4.5和4.5.2预发布测试,CFLAGS =“ - O2 -std = c ++ 0x -pedantic -Wall -Wextra”)编译,但会产生内部头错误(C2664) )在MSVC 2010上。(如果需要,我可以提供错误输出,根本没有对我的代码(!)的引用)。

我在MSVC中发现了一个错误吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

为什么不使用lambda?为了这种目的,所有绑定内容都已被弃用。

double primeValue( const func1D &func,
                   const double lowerBound, const double upperBound,
                   const double pole )
{
    // check bounds
    if( lowerBound >= upperBound )
        throw runtime_error( "lowerBound must be smaller than upperBound!" );

    // C++0x way of writing: fullFunc(x) = func(x)/(x-a)
    auto fullFunc = [=](double d) {
        return func(d) / (d - pole);
    };

    // pole not in domain
    if( pole<lowerBound || pole>upperBound)
    {
        cout << "Case 1" << endl;
        return integrateSimpson( fullFunc, 1000, lowerBound, upperBound );
    }
    // pole closer to upper bound
    else if( upperBound-pole < pole-lowerBound  )
    {
       cout << "Case 2" << endl;
       // C++0x way of writing g(x) := [f(x)-f(2a-x)]/(x-a)
       auto specialFirstFunc = [=](double x) -> double {
           double numerator = func(x) - func(2*pole - x);
           return numerator / (x - pole);
       };
        const double trickyPart = integrateSimpson( specialFirstFunc, 1000, pole+.000001, upperBound );

        const double normalPart = integrateSimpson( fullFunc, 1000, lowerBound, 2.*pole-upperBound );
        cout << "Tricky part: " << trickyPart << endl;
        cout << "Normal part: " << normalPart << endl;
        return trickyPart + normalPart;
    }
    else // pole closer to lower bound
    {
        cout << "Case 3" << endl;
        // C++0x way of writing g(x) := [f(x)-f(2a-x)]/(x-a)
       auto specialFirstFunc = [=](double x) -> double {
           double numerator = func(x) - func(2*pole - x);
           return numerator / (x - pole);
       };
         const double trickyPart = integrateSimpson( specialFirstFunc, 1000, lowerBound, pole-.00001 );

         const double normalPart = integrateSimpson( fullFunc, 1000, 2.*pole-lowerBound, upperBound );
         cout << "Tricky part: " << trickyPart << endl;
         cout << "Normal part: " << normalPart << endl;
         return trickyPart + normalPart;
    }
}

至于你是否真的在MSVC中发现了一个错误,我不知道,但你的解决方案绝对没必要 - 这段代码更清晰,更易于维护。