2012-09-10 244 views
8

我最近花了相當長的一段時間,這段代碼調用func()時理解錯誤消息:奇怪的編譯器錯誤():「成員函數已經定義或聲明」,而不是「參考參考」

int main() 
{ 
    vector< vector<double> > v; 

    double sum = 0; 
    for_each(v.begin(), v.end(), 
     bind2nd(ptr_fun(func), &sum)); 

    return 0; 
} 

func()被宣佈像這樣,代碼編譯的罰款:

void func(vector<double> v, double *sum) 
{ 
} 

,當我用這個聲明(效率),我得到了一個編譯器錯誤:

void func(const vector<double> &v, double *sum) 
{ 
} 

我期望看到的錯誤是像一個參考 - 參考錯誤,因爲運營商(binder2nd的)的定義,

result_type operator()(const argument_type& _Left) const 

相反,我驚訝的是, Visual C++(VS2012)編譯器給我的錯誤是:

error C2535: 'void std::binder2nd<_Fn2>::operator()(const std::vector<_Ty> &) const' : member function already defined or declared

我不能解密。

  • 你能解釋下其機制operator()已經 定義

完整的錯誤我得到的是:

error C2535: 'void std::binder2nd<_Fn2>::operator()(const std::vector<_Ty> &) const' : member function already defined or declared 
with 
[ 
    _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)>, 
     _Ty=double 
] 
c:\vc\include\xfunctional(319) : see declaration of 'std::binder2nd<_Fn2>::operator()' 
with 
[ 
     _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)> 
] 
c:\consoleapplication1.cpp(31) : see reference to class template instantiation 'std::binder2nd<_Fn2>' being compiled 
with 
[ 
     _Fn2=std::pointer_to_binary_function<const std::vector<double> &,double *,void,void (__cdecl *)(const std::vector<double> &,double *)> 
] 

Build FAILED. 
+3

由於您使用VS 2012,我認爲您可以切換到C++ 11並使用lambda/std :: bind來避免這些棄用的東西。 – kennytm

+1

看起來像它指的是binder2nd結構的op(),由於參考摺疊(或類似的)被定義了兩次相同的簽名。 – PlasmaHH

+0

這很有趣。看起來你不能在舊的活頁夾包裝中使用引用參數類型?! –

回答

6

此行爲已定義良好(每個正確的C++編譯器都無法編譯您的代碼)。

從上類模板binder2nd標準(N3376)部分D.9.3operator()這兩個defintions存在:

typename Fn::result_type 
operator()(const typename Fn::first_argument_type& x) const; 

typename Fn::result_type 
operator()(typename Fn::first_argument_type& x) const; 

如果first_argument_type已經是const T&,那麼他們將是相互矛盾的。

+0

+1,如果'first_argument_type'已經是'T&',那麼這似乎就成了一個問題?至少我發現'std :: bind2nd(std :: ptr_fun(f),「xyz」);'如果'f'是'void f(std :: ostream&str,const char * S);'。唉,按值傳遞'std :: ostream'不是一個選項,所以你似乎必須求助於傳遞一個指針。 : - / –

0

這不是一個答案,但我只是想記錄了現代C++ 11解決方案,其中所有的小幫手綁定在棄用贊成普遍std::bind的:

#include <functional> 
#include <vector> 
#include <algorithm> 

void func(std::vector<double> const & v, double * sum) { /* ... */ } 

int main() 
{ 
    std::vector<std::vector<double>> v; 
    double sum = 0; 
    std::for_each(v.begin(), v.end(), std::bind(func, std::placeholders::_1, &sum)); 
} 

的C++ 11的可變參數模板,以及類型改變性狀更全面地收集,給std::bind強得多演繹能力比0以前的組件。