1

次のように、関数呼び出し演算子をテンプレート関数でオーバーロードするクラスがあります。

class Test
{
public:
    template<class T>
        void operator()(T t)
    {
        std::cout<<(&t)<<std::endl;
    };
};

参照引数で呼び出したいのですが、そうしようとすると、代わりに引数が値として渡されます。これが私のテスト設定です:

template<class T>
    void test(T t) {std::cout<<(&t)<<std::endl;}

int main(int argc,char *argv[])
{
    Test t;
    int i = 5;
    std::cout<<(&i)<<std::endl;
    t((int&)i); // Passes the argument as a value/copy?
    test<int&>(i); // Passes the argument as a reference
    while(true);
    return 0;
}

出力は次のとおりです。

0110F738 -- 'i' のアドレスの出力

0110F664 -- テンプレート オーバーロードの引数のアドレスの出力

0110F738 -- 'test' による引数のアドレスの出力

テンプレート関数 'test' は単に検証用です。

Visual Studio デバッガーは、テンプレートのオーバーロードに 'int&' ではなく 'int' を使用していることを確認します。

test_function_call.exe!Test::operator()(int t) 9 行目 C++

代わりに参照を使用するように強制するにはどうすればよいですか? テンプレート関数呼び出し演算子で <> を使用して型を指定する方法はありますか?

4

2 に答える 2

2

これは、テンプレート型推定を実行するときに、cv 修飾子とパラメーターの参照性が破棄されるためです。std::ref代わりにラッパーを介して渡します

t(std::ref(i));

簡単な例:

#include <iostream>
#include <functional>

template<typename T>
void f(T param)
{
    ++param;
}

int main()
{
    int i = 0;
    f(std::ref(i));
    std::cout << i << std::endl; // i is modified here, displays 1
}
于 2015-05-22T17:56:54.830 に答える