<functional> (вложенное связывание) проблемы с MSVC 2010 - PullRequest
0 голосов
/ 24 октября 2010

У меня есть следующий код (извините за длину):

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;
    }
}

Он интегрирует функции по вещественной оси, которые содержат особенность (полюс), используя концепцию главных значений из математической областикомплексного анализа.Детали bind и function изменяют исходную функцию f (x) на

(f (x) -f (2 * pole-x)) / (xa)

Он даже дает правильный результат для моей простой функции теста.Дополнительные сведения, которые я могу предоставить по запросу:

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

Последнее интегрируется с использованием простого правила интеграции Симпсона.Код может быть предоставлен, но он не очень актуален для рассматриваемой проблемы.

Это прекрасно работает с GCC 4.4+ (протестировано с предварительным выпуском 4.4.5 и 4.5.2, CFLAGS = "- O2 -std =c ++ 0x -pedantic -Wall -Wextra "), но выдает внутренние ошибки заголовка (C2664) в MSVC 2010. (При необходимости могу предоставить вывод ошибок, вообще нет ссылок на мой код (!)).

Нашел ли я ошибку в MSVC?

Спасибо!

1 Ответ

0 голосов
/ 24 октября 2010

Почему бы просто не использовать лямбду? Для этой цели все связующие материалы устарели.

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, я не знаю, но ваше решение определенно не нужно - этот код намного чище и проще в обслуживании.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...