私は大きなシーケンスの2つのベクトルを持つクラスを設計しようとしています。どのようにl-value ref、r-value ref、およびinitializer_listのすべてを許可するテンプレートコンストラクタを作成できますか?
std::vector<double> factory() {
return std::vector<double>{1,2,3}; // it actually generates a large sequence of double
}
struct my_class {
my_class(const std::vector<double>& x, const std::vector<double>& y)
: m_x(x), m_y(y)
{ }
std::vector<double> m_x;
std::vector<double> m_y;
};
int main() {
my_class c(factory(), factory());
my_class c2(factory(), {0.5, 1, 1.5});
}
よく動作しますが、ベクターの移動コンストラクタは使用しません。だから私は完璧な転送でr値の参照を受け入れるようにコンストラクタを変更しようとしました。
struct my_class {
template<typename X, typename Y>
my_class(X&& x, Y&& y
, typename std::enable_if<std::is_convertible<X, std::vector<double> >::value &&
std::is_convertible<Y, std::vector<double> >::value>::type * = 0
)
: m_x(std::forward<X>(x)), m_y(std::forward<Y>(y))
{ }
std::vector<double> m_x;
std::vector<double> m_y;
};
これで問題が発生しました。 initializer_listを使ってインスタンスを構築しようとすると、このようなエラーが出ます。
$ g++ -W -Wall -std=gnu++0x a.cpp
a.cpp: In function ‘int main()’:
a.cpp:34:32: error: no matching function for call to ‘my_class::my_class(std::vector<double>, <brace-enclosed initializer list>)’
a.cpp:17:18: note: candidate is: my_class::my_class(const my_class&)
私はstd::initializer_list<double>
がstd::vector<double>
に変換可能でないかもしれないと思ったが、それは実際に転換され、私はenable_if引数なしにしようとしたとき、私は同じエラーを得ました。何か不足していますか?
g ++のどのバージョンを使用していますか? IIRCの 'initializer_list'サポートはいくつかの最近のバージョンでは不完全でした。 – Flexo
@awoodland gcc 4.6.2を使用しています。 「不完全」とはどういう意味ですか? – kukyakya