web-dev-qa-db-ja.com

C ++-ステートメントはオーバーロードされた関数のアドレスを解決できません

スタンドアロン行として次のように入力すると、

std::endl;

次のエラーが発生しました:

statement cannot resolve address for overloaded function

何故ですか?書きませんstd::endl;スタンドアロンラインとして?

ありがとう。

20
Simplicity

_std::endl_ は関数テンプレートです。通常、挿入演算子_<<_の引数として使用されます。その場合、問題のストリームの_operator<<_は次のように定義されます。 ostream& operator<< ( ostream& (*f)( ostream& ) )fの引数の型が定義されているため、コンパイラーは関数の正確なオーバーロードを知ることができます。

それはこれに匹敵します:

_void f( int ){}
void f( double ) {}
void g( int ) {}
template<typename T> void ft(T){}

int main(){
  f; // ambiguous
  g; // unambiguous
  ft; // function template of unknown type...
}
_

しかし、いくつかの型ヒントによって曖昧さを解決できます。

_void takes_f_int( void (*f)(int) ){}

takes_f_int( f ); // will resolve to f(int) because of `takes_f_int` signature
(void (*)(int)) f; // selects the right f explicitly 
(void (*)(int)) ft; // selects the right ft explicitly 
_

_std::endl_の引数として指定した場合、これが_operator <<_で通常発生します。関数の定義があります。

_ typedef (ostream& (*f)( ostream& ) ostream_function;
 ostream& operator<<( ostream&, ostream_function )
_

そしてこれにより、コンパイラは_std::endl_の適切なオーバーロードを選択できるようになります。 _std::cout << std::endl;_。

いい質問だ!

16
xtofl

std::endlは関数テンプレートです。テンプレート引数を一意に決定できないコンテキストで使用する場合は、どの特殊化を意味するかを明確にする必要があります。たとえば、明示的なキャストを使用したり、正しい型の変数に割り当てたりすることができます。

例えば.

#include <ostream>

int main()
{
    // This statement has no effect:
    static_cast<std::ostream&(*)(std::ostream&)>( std::endl );

    std::ostream&(*fp)(std::ostream&) = std::endl;
}

通常は、テンプレート引数が自動的に推定されるコンテキストで使用します。

#include <iostream>
#include <ostream>
int main()
{
    std::cout << std::endl;
    std::endl( std::cout );
}
3
CB Bailey

私が考えることができる最も多くの可能性がある理由は、その宣言が次のとおりであることです:

ostream& endl ( ostream& os );

言い換えると、<<操作の一部でなければ、推論できるosはありません。私はこれが次の行からそうであると確信しています:

std::endl (std::cout);

正常にコンパイルされます。

あなたへの私の質問は、次のとおりです。なぜwantがこれを行うのですか?

7;がCで完全に有効なステートメントであることは知っていますが、そのようなごみが私のコードを汚染しているのはわかりません:-)

3
paxdiablo

endlは、パラメーターを受け取る関数です。 std :: endl on cplusplus.com を参照してください

// This works.
std::endl(std::cout);
2
sinelaw

http://www.cplusplus.com/reference/iostream/manipulators/endl/

パラメータのタイプとして_std::endl_が必要なため、_basic_ostream_を単独で使用することはできません。それはそれが定義される方法です。

これは、関数がmy_func()として定義されているときにvoid my_func(int n)を呼び出そうとするようなものです。

2
Marlon

std :: endlはマニピュレータです。実際には、ストリーム上の<<演算子のaバージョンによって呼び出される関数です。

std::cout << std::endl
// would call 
std::endl(std::cout).
2
hbn

std::endlは行を終了し、バッファをフラッシュします。したがって、coutなどのストリームに接続する必要があります。

1