5

後で定義される関数に依存している場合、関数ルックアップに関する奇妙な動作に気付きました。

#include <iostream>

template <typename T>
void foo(const T&)
{
    std::cout << "Basic" << std::endl;
}

template <typename T>
void bar()
{
    T x;
    foo(x);
}

void foo(const int& x)
{
    std::cout << "int:" << x << std::endl;
}

int main()
{
    bar<int>();
}

出力:

Basic

何らかの理由で、その下のオーバーロードを見つけるためにfooinsideを使用することを期待していました。barのオーバーロードfooを上に移動barすると、出力が望ましいものになりますint:0(または宣言を書くだけです)。

この同じ動作は、二項演算子のオーバーロードには適用されないようです。

#include <iostream>

struct Foo {} foo;

template <typename T>
void operator<<(const Foo&, const T&)
{
    std::cout << "Basic" << std::endl;
}

template <typename T>
void bar()
{
    T x;
    foo << x;
}

void operator<<(const Foo&, const int& x)
{
    std::cout << "int:" << x << std::endl;
}

int main()
{
    bar<int>();
}

出力:

int:0

2 つの質問があります。1 つ目は、なぜこのような動作になるのか、また演算子のオーバーロードではなぜ異なるのかということです。2 つ目: 名前付き関数がある場合 ( の使用のように)、後で翻訳単位で宣言されたオーバーロードされた s を検出するような方法でfoo関数を作成する方法はありますか?barfoo

4

1 に答える 1