私は、さまざまなタイプとそのタイプのような ACTS を使用して、いくつかの役立つタスクを処理するクラスを持っています。インポート部分は、クラスが次のようになることです。
template <typename Super>
class Wrapper : public Super
{
public:
Wrapper ()
: Super ()
{ }
template <typename Arg1>
Wrapper ( Arg1 const & arg1 )
: Super ( arg1 )
{ }
// More like that...
} ;
アイデアは、通常は次のように呼び出す場合です。
MyClass1 * pObject1 = new MyClass1 ( "My String" ) ;
MyClass2 * pObject2 = new MyClass2 () ;
代わりに次のように呼び出すことができます:
MyClass1 * pObject1 = new Wrapper<MyClass1> ( "My String" ) ;
MyClass2 * pObject2 = new Wrapper<MyClass2> () ;
(注: これを行う必要性について質問しないでください。必要性はあります。)
場合によっては、Super にデフォルトのコンストラクターが含まれることがあります。時々、そうではありません。しかし、Wrapper クラスは常に同じです。
問題: Visual Studio 2010 には初期のテンプレート インスタンス化のバグがあるようで、クラスがインスタンス化されると (呼び出されていない場合でも!) デフォルト コンストラクターがインスタンス化され、アクセス許可エラーまたはメソッドが見つからないエラーが発生します。エラー(スーパーによって異なります)。
テンプレート化されたコンストラクターは使用されるまでインスタンス化されないため、この問題は発生しません。そこで、これを使ってデフォルトのコンストラクタを修正したいと思います。
このコードはすべて、GCC 4.2、GCC 4.1、および LLVM 4.2.1 で完全に機能することに注意してください。同じ CMakeLists ファイルから makefile、X-Code プロジェクト ファイル、および VS2010 プロジェクト ファイルを cmake で生成することさえあります。まったく同じコード (これらのクラスを使用しないマイナーな低レベルの抽象化のものを除く) が両方に使用されます。
私が試したことの1つ(失敗):
template <typename Super>
class Wrapper : public Super
{
public:
struct DummyStruct { } ;
template <typename Arg1>
Wrapper ( Arg1=int() , DummyStruct=DummyStruct() )
: Super ()
{ }
template <typename Arg1>
Wrapper ( Arg1 const & arg1 )
: Super ( arg1 )
{ }
// More like that...
} ;
VS2010 は、Wrapper にデフォルトのコンストラクターが見つからないと文句を言いますが、どのコンテキストで呼び出されているかはわかりません。
Wrapper のデフォルト コンストラクターをオンデマンドのみにする方法についての提案 (標準ではそうあるべきです) を大歓迎します! ありがとうございました!
更新/詳細 (2012 年 12 月 8 日 10.22 MST):
VSが不平を言う特定のケースはこれです:
class MyGenericSuper
{
public:
MyGenericSuper ( std::string const & inOnlyArgument )
{ }
} ;
class MyClass : Wrapper<MyGenericSuper>
{
public:
MyClass ( std::string const & inOnlyArgument )
: Wrapper<MyGenericSuper> ( inOnlyArgument )
{ }
} ;
MyGenericSuper のすべてのサブクラスはまったく同じコンストラクターを持ち、その引数をスーパーに渡します。また、それらは抽象ファクトリからのみインスタンス化されるため、その 1 つの引数を使用してのみ作成することが保証されます (ファクトリのみが作成するため)。
さらに、Wrapper を使用するクラスは 1 つしかなく (これがエラーの場所のようです)、そのスーパーを呼び出すデフォルトのコンストラクターがありません...