2010-10-24 59 views
0

我有以下代碼(我的冗長抱歉):<functional>(嵌套綁定)問題MSVC 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; 
    } 
} 

過來包含一個奇點(極)實軸集成功能使用複雜分析的數學領域的主要價值觀念。該bindfunction部分修改原函數f(x),以

(F(X)-f(2 *極-X))/(XA)

它甚至給他糾正結果爲我的簡單測試用例函數。如果需要,我可以提供其他詳細信息:

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中發現了一個錯誤嗎?

謝謝!

+4

「我在MSVC中發現了一個錯誤嗎?」 - 如果你這樣做,我不會感到驚訝。 :) – casablanca 2010-10-24 17:48:59

+0

這可能是相關的:http://stackoverflow.com/questions/2425277/visual-studio-2010-and-stdfunction但我不明白接受的答案建議做什麼... – rubenvb 2010-10-24 17:51:43

回答

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的錯誤,我不知道,但你的解決方案是絕對必要的方式 - 這個代碼是更乾淨,更容易維護。

+1

那麼,作爲最Linux發行版和我自己仍然使用GCC 4.4,lambda的不是一個選項。我不認爲'std :: bind'已經被棄用了......但是lambda的方式比之前向我演示的要短:http://stackoverflow.com/questions/4008369/combining-stdfunction-objects – rubenvb 2010-10-24 18:06:41

+0

@rubenvb :蘭布達斯是特別引入到語言中的,因爲綁定吸引了其他原因。只需打一個#ifdef就可以了。很可能,MSVC的庫與C++ 0x現在作爲標準有些過時 - 例如,_1被定義爲std :: placeholders :: _ 1而不是std :: _ 1。我檢查了這個鏈接 - 他明確地爲他捕獲的每個變量設置了參考或值,而我設置了我的值來捕獲所有變量。 – Puppy 2010-10-24 18:09:33

+0

@DeadMG:那麼,lambda解決方法聽起來不錯,但我認爲內部實現反正使用'std :: bind'(它給出了相同的錯誤:s)。我檢查了使用的'#ifdef'分支,並且在內部使用'std :: bind'對其進行了編譯。 – rubenvb 2010-10-24 18:25:47