ERROR:invalid initialization of non-const reference of typeを直す

Visual Studio(MSVC)からGCCに移植する際に食らったエラーメモ。

#include <iostream>
template<class T_>
int hoge(int value, T_ & x)
{
	return x(value);
}

struct PlusOne
{
	int operator()(int x){ return x + 1; }
};
int main()
{
	std::cout << "hoge: " << hoge(1, PlusOne()) << std::endl;
	return 0;
}

上の適当コード、これはMSVCコンパイルできるが、GCCだと

$ g++ main.cpp
main.cpp: 関数 ‘int main()’ 内:
main.cpp:15:44: エラー: invalid initialization of non-const reference of type ‘PlusOne&’ from an rvalue of type ‘PlusOne’
  std::cout << "hoge: " << hoge(1, PlusOne()) << std::endl;
                                            ^
main.cpp:4:5: 備考: in passing argument 2 of ‘int hoge(int, T_&) [with T_ = PlusOne]’
 int hoge(int value, T_ & x)
     ^

となりアウト。これを直すにはhoge関数の引数をconst参照にするようにして、かつ、それに合わせてPlusOne構造体のoperator()もconstにすればOK。

#include <iostream>
template<class T_>
int hoge(int value, const T_ & x)
{
	return x(value);
}

struct PlusOne
{
	int operator()(int x) const{ return x + 1; }
};
int main()
{
	std::cout << "hoge: " << hoge(1, PlusOne()) << std::endl;
	return 0;
}

あるいは

PlusOne plus_one;
std::cout << "hoge: " << hoge(1, plus_one) << std::endl;

として一旦実態持たせておくでもOKだった。

今回はちゃんとするなら確かにconst入れるのが筋なので、全部書き直すためにずっとconst, constしていた。