0
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <functional>
#include <deque>
using namespace std;

#include <tr1/functional>
using namespace std::tr1::placeholders;
template<class Function_t>
void for_each_x(Function_t func,int interval)
{
   for(int sc = 0; sc < 10; sc+=interval){
      func((const int)sc);
   }
}
void foo(int x,const int y)
{
}

int main(int argc, char *argv[])
{
   for_each_x(tr1::bind(tr1::function<void(int,const int)>(foo),_1,11),2);
   return 0;
}

gcc 4.2.2 または 4.4.1 で非常に長いエラー メッセージが表示されます。「const int」を「int」に変更すると、エラー メッセージは表示されません。しかし、関数の引数が参照によって渡された場合にカウンター変数が誤って変更されないようにするために、「const int」が本当に好きです。

4

1 に答える 1

3

式は、その型によって分類されるだけでなく、その左辺値によっても分類されます。これは主にどこかに保存されているかどうかを決定し、非 const 参照にバインドできるかどうかも決定します。非 const 右辺値 (非左辺値) は非 const 参照にバインドできないため、次の操作を行うと常に失敗します。

template<typename T>
void f(T&);
int main() { f(10); f((int const)10); }

2 番目の呼び出しに驚かれるかもしれませんが、実際には cv-qualifiers は非クラスの右辺値から削除されるため、キャスト式はたまたま typeintのままです。したがって、関数テンプレートのパラメーターの型は次のように推定されint&ます - コンパイルは失敗します。

現在、C++0x より前のバージョンbindでは、転送する引数の型として非 const 参照のみがサポートされているため、const 引数を指定しても問題ありません。テンプレート化されたパラメーターにより、const 参照になります。ただし、const 以外の引数を与え、それが右辺値である場合は、参照パラメーターによってバインドできないため、問題ありません

左辺値を使用してバインド オブジェクトを呼び出します。つまりsc、const 左辺値にキャストするかキャストします。また、関数パラメーター型のトップレベル修飾子が削除され、foo事実上型があることにも注意してvoid(int, int)ください。このトップレベルの cv 削除は、すべての型のパラメーターに対して発生します。とにかく、解決策は呼び出しを変更することです

for(int sc = 0; sc < 10; sc+=interval){
   func((int const&)sc); // notice &
}
于 2009-11-05T10:26:49.627 に答える