is_callable<F, Args...>
少し前に、トレイトを書きたいときに、いくつかのコードの次の動作に混乱しました。過負荷の解決では、非定数refによる引数を受け入れる関数は呼び出されませんよね?コンストラクターが必要なため、次のように拒否しないのはなぜTest&
ですか?かかると思っていましたf(int)
!
struct Test {
Test() { }
// I want Test not be copyable from rvalues!
Test(Test&) { }
// But it's convertible to int
operator int() { return 0; }
};
void f(int) { }
void f(Test) { }
struct WorksFine { };
struct Slurper { Slurper(WorksFine&) { } };
struct Eater { Eater(WorksFine) { } };
void g(Slurper) { }
void g(Eater) { } // chooses this, as expected
int main() {
// Error, why?
f(Test());
// But this works, why?
g(WorksFine());
}
エラーメッセージは
m.cpp: In function 'int main()':
m.cpp:33:11: error: no matching function for call to 'Test::Test(Test)'
m.cpp:5:3: note: candidates are: Test::Test(Test&)
m.cpp:2:3: note: Test::Test()
m.cpp:33:11: error: initializing argument 1 of 'void f(Test)'
一方が機能するのにもう一方が機能しない理由を説明していただけますか?