私のVS2010は、このコードはコンパイルできない理由:使用のstd :: tr1を::バインド::一back
#include <functional>
#include <vector>
int main()
{
std::vector<int> vec;
std::bind(&std::vector<int>::push_back, std::ref(vec), 1)();
return 0;
}
私のVS2010は、このコードはコンパイルできない理由:使用のstd :: tr1を::バインド::一back
#include <functional>
#include <vector>
int main()
{
std::vector<int> vec;
std::bind(&std::vector<int>::push_back, std::ref(vec), 1)();
return 0;
}
これを試してみてください:push_back
はローカル型にすることはできませんというC++ 03のノートで
struct push_back {
void
operator()(std::vector<int>& vector, int i) const
{
vector.push_back(i);
}
};
// somewhere else:
std::vector<int> vec;
std::tr1::bind(push_back(), std::tr1::ref(vec), 1)();
を。 C++ 11では可能ですが、ラムダを使うのはもっと慣用的(完全に同等)です。
あなたの実装ではstd::vector<T>::push_back
のオーバーロードが提供されるため、そのアドレスは曖昧さを排除する必要があります。これが起こった場合、コンパイラは適切なエラーメッセージを提供する必要があります。 すべての場合は、「可能ではありません」という意味を説明する必要があります。
点は、ヘルパーに 機能を使用しないことです。 - マゼンタ
なぜあなたはそれを質問に入れませんでしたか?私はあなたの心を読むことができません。
また、これを試すことができます:私は成功に保証されていないと信じて
std::vector<int> vec;
void (std::vector<int>::*push_back)(int const&) = &std::vector<int>::push_back;
std::tr1::bind(push_back(), std::tr1::ref(vec), 1)();
。
このようなヘルパー関数を使用しないことがポイントです。 – magenta
@magentaあなたの質問を修正してください。 –
をそれはpropablyこのよう洛必要があります。
std::vector<int> vec;
std::tr1::bind(&std::vector<int>::push_back, std::tr1::ref(vec), _1)(1);
違いはありません。 – magenta
なぜあなたのためにこれがうまくいかないのか、より具体的にする必要があります。
#include <iostream>
#include <tr1/functional>
#include <vector>
int main(int argc, char* argv[]) {
std::vector<int> vec;
std::tr1::bind(&std::vector<int>::push_back, std::tr1::ref(vec), 1)();
std::cout << "vec.size = " << vec.size() << std::endl;
std::cout << "vec[0] = " << vec[0] << std::endl;
return 0;
}
$ gcc -o test -lstdc++ test.cpp && ./test
vec.size = 1
vec[0] = 1
更新:リュックダントンは、ここでの問題が過負荷push_back
あり、権利です。質問Are there boost::bind issues with VS2010 ?を参照してください。また、問題はpush_back
に限定されず、Visual Studio 2010 and boost::bindを参照してください。
最終行は、ポータブル C++では実行しようとしていないことです。 std::vector<>::push_back
は、少なくともlvaluesのオーバーロードとrvaluesのオーバーロードが必要であるため、C++ 11コンパイラでオーバーロードされることが保証されています。
:
引数なしでオーバーロードされた関数名の使用は、関数、関数へのポインタ、またはオーバーロードセットの特定の関数のメンバ関数へのポインタに特定のコンテキストで解決されます。関数テンプレート名は、そのようなコンテキストでオーバーロードされた関数のセットを指定すると見なされます。 選択された機能は、そのタイプがコンテキストで必要とされるターゲットタイプの関数タイプと同一であるものです。 [注:つまり、関数がメンバであるクラスは、メンバ関数へのポインタ型と一致するときに無視されます。末端音符]ターゲットは
- 初期化されたオブジェクトまたは参照、
- 割り当ての左側、
- 関数のパラメータ、
- ユーザのパラメータとすることができます
- 関数、演算子関数、または変換の戻り値
- 明示的な型変換または
- 非型テンプレートパラメータ。
オーバーロードされた関数名の前には、
&
演算子を付けることができます。オーバーロードされた関数名は、リストされている以外のコンテキストでは、引数なしでは使用できません。 [注:オーバーロードされた関数名を囲む括弧の冗長な集合は無視されます。 末端ノート]
問題は§17.6.5.5/ 2から来ている:
実装は、デフォルトで引数を追加することにより、クラス内で追加の非仮想メンバ関数のシグネチャを宣言してもよいです値をメンバ関数の署名に変換する。 したがって、C++標準ライブラリのクラスのメンバ関数のアドレスは、不特定の型を持ちます。
したがって、定義によって実装することにより、実装基づい除く不可知である、そのような表現のタイプとして、これまでの標準ライブラリのクラスのメンバ関数のアドレスを取得するポータブルではありません。
リュックダントンの提案回避策(具体的には、ラムダを使用して)私が推薦する何もである:
std::vector<int> vec;
[&](){ vec.push_back(1); }();
はい、私たちがC++ 0xを使用するならば、ラムダがおそらく最良の選択です。しかし、実際に私はVS2010が私のコードをコンパイルできなかったのは不思議でした。 – magenta
ペースト状にしてくださいあなたが取得しているエラー。たとえ私たちが助けようとしていても、私たちは霊能者ではありません。 – ereOn
私はこれに誤りを見ない。私はそのコードを実行し、それはうまく動作します。 tr1/functionalを必ず含めてください。 –
VS2010ではコンパイルされず、ヘッダーはありません。ちょうどです。私は間違って何をしていますか? –
magenta