他のクラスからコンストラクターを継承する必要があるクラスを作成しようとしていますが、それらのクラス自体から継承する必要はありません。
クラスの初期化中のある時点で、完全転送を使用して、コンストラクターが指定された引数と一致する型のオブジェクトを作成したいと考えています。
引数のないデフォルトのコンストラクターを除いて、あいまいさはありません。
これは私のコードです:
#include <string>
using namespace std;
//NOTE: this class is just an example to demonstrate the problem
class String {
public:
//default constructor to prevent ambiguity
String() {}
//construct from wstring
template<typename... Args>
String(enable_if<is_constructible<wstring, Args...>::value, Args>::type&&... args) : ws(forward<Args>(args)...) {}
//construct from string
template<typename... Args>
String(enable_if<is_constructible<string, Args...>::value, Args>::type&&... args) : s(forward<Args>(args)...) {}
private:
string s;
wstring ws;
};
void foo(const String& string) {
}
int main()
{
foo(L"123");
foo("123");
return 0;
}
私は多くのことを試しましたが、うまくいきません。
- 現在のアプローチ
enable_if
では、テンプレート引数を自動的に差し引くことができません(私は思う) - コンストラクターを使用
enable_if
しているため、戻り値には使用できません - コンストラクターが可変長であるため、別のデフォルトパラメーターを追加しても機能し
enable_if
ません - 関数の引数から削除すると
enable_if
、コンパイラは無効なオーバーロードについて不平を言います(もちろん)
この問題を解決するエレガントな方法はありますか?
編集: 標準で許可されている1つの暗黙的な変換は、私のクラスでは発生しないはずです。[コード例を編集]
上記の例で機能する 1 つの解決策は、単一の可変引数コンストラクターを定義し、引数を条件付き初期化関数に完全転送することです。ただし、メンバーはデフォルトで構築される必要があり、これは他の場合には機能しない可能性があるため、このオーバーヘッドを回避したいと思います。
(物事をより明確にすることができる場合は、自由に質問を編集してください)