次のコードがあります。
#include <iostream>
#include <typeinfo>
template <typename T>
struct A : T {
template <typename ...Args>
A(Args&&... params) : T(std::forward<Args>(params)...), x(0) {
std::cout << "Member 'x' was default constructed\n";
}
template <typename O, typename ...Args, typename = typename std::enable_if<std::is_constructible<int,O>::value>::type>
A(O o, Args&&... params) : T(std::forward<Args>(params)...), x(o) {
std::cout << "Member 'x' was constructed from arguments\n";
}
int x;
};
struct B{
B(const char*) {}
};
int main() {
A<B> a("test");
A<B> y(3, "test");
return 0;
}
正常に動作し、印刷されます
Member 'x' was default constructed
Member 'x' was constructed from arguments
ただし、2 番目のオーバーロードの最初の引数が参照の場合、突然 2 番目のオーバーロードが取得されなくなり、コンパイルが失敗します。
template <typename O, typename ...Args, typename = typename std::enable_if<std::is_constructible<int,O>::value>::type>
A(O& o, Args&&... params) : T(std::forward<Args>(params)...), x(o) {
std::cout << "Member 'x' was constructed from arguments\n";
} // Note the O& in the arguments
どうしてこれなの?それを修正してコピーを避けることは可能ですか?
編集:ユニバーサル参照を使用すると、明らかに再び機能します。私が実際に望んでいるものであるconst
参照も機能しません。
さらに、入力パラメーターを別の値に保存しても (右辺値を避けて)、機能しません。
int main() {
double x = 3.0;
A<B> y(x, "test"); // Still not working
return 0;
}