テンプレート化された関数を使用して、テンプレート クラスのコンストラクターのパラメーターの既定値を返そうとしています。関数のテンプレート パラメーターは、クラスのテンプレート パラメーターでもあります。以下に例を示しました。
背景 この例は、私のアプリケーションでも発生する正確なユースケースと依存関係を示しています。クラス X は実際には、小さなブロックに分割された大きなデータ ブロックを管理する非常に大きなクラスです。クラス ヘルパーは、小さなブロックのサイズでメモリを割り当てて解放するメモリ マネージャです。実際には、GetHelper 関数は実行時にヘルパーのいくつかのコンストラクター パラメーターを推測しようとするため、この設計を使用しました。
実際の質問 マクロ USE_NS と SHOW_ERROR の両方が定義されている場合、コードはコンパイルされず、エラー C2783 could not deduce template argument at line 66 が発生します。ここで、テンプレート化された関数 GetHelper (テンプレートを提供するパラメーター!)。GetHelper は、クラス X とは異なる名前空間からのものであることを思い出してください。72 行目では、ctor 本体内の Helper オブジェクトを初期化するために、同じ関数呼び出しが使用されていることにも注意してください。なにが問題ですか?解決策または回避策はありますか?
私は Visual Studio 2008 Pro を使用しており、1.47 をブーストしています。
#include <iostream>
#include <boost/shared_ptr.hpp>
// 1 means macro is defined
// USE_NS 1 and SHOW_ERROR 1 -> Compileerror
// USE_NS 0 and SHOW_ERROR 1 -> Works, Output: 8 and 16.5
// USE_NS 1 and SHOW_ERROR 0 -> Works, Output: 3
// USE_NS 0 and SHOW_ERROR 0 -> Works, Output: 3
#define USE_NS
#define SHOW_ERROR
#ifndef USE_NS
#define NH
#define NX
#endif
#ifdef USE_NS
namespace NH
{
#endif
template< typename TNumAtH, size_t TSizeAtH>
class Helper
{
public:
TNumAtH* x;
Helper()
{
x = new TNumAtH[TSizeAtH];
x[0] = static_cast< TNumAtH >( 8 );
}
~Helper()
{
delete [] x;
}
};
template <typename TNumAtF, size_t TSizeAtF >
boost::shared_ptr< Helper< TNumAtF, TSizeAtF > > GetHelper()
{
return boost::shared_ptr< Helper< TNumAtF,TSizeAtF > > ( new Helper< TNumAtF, TSizeAtF >() );
}
#ifdef USE_NS
}
namespace NX
{
#endif
template< typename TNumAtX, size_t TSize >
class X
{
public:
boost::shared_ptr< NH::Helper< TNumAtX, TSize > > a;
#ifdef SHOW_ERROR
//this produces an error if namespace are used, if no namespaces are used
//NH is reduced to a blank (see macros at line 17 and 18
X( boost::shared_ptr< NH::Helper< TNumAtX, TSize > > h = NH::GetHelper< TNumAtX, TSize >() );
#endif
X( TNumAtX firstElem )
{
//this works with namespaces and without namespaces
a = NH::GetHelper< TNumAtX, TSize >();
a->x[0] = firstElem;
}
TNumAtX GetNum()
{
return a->x[0];
}
};
#ifdef SHOW_ERROR
template< typename TNumAtX, size_t TSize >
X<TNumAtX, TSize>::
X( boost::shared_ptr< NH::Helper< TNumAtX, TSize > > h ) : a( h )
{
}
#endif
#ifdef USE_NS
}
#endif
int main( int argc, char** argv )
{
std::cout << "Hello at TestTemplateFunction" << std::endl;
//use case one
#ifdef SHOW_ERROR
NX::X<int, 5> x1;
#else
NX::X<int, 5> x1( 3 );
#endif
std::cout << "Use case 1: " << x1.GetNum() << std::endl;
//use case two
#ifdef SHOW_ERROR
typedef float T;
size_t const N = 9;
boost::shared_ptr< NH::Helper<T, N> > h( new NH::Helper<T, N> );
h->x[0] = 16.5f;
NX::X<T, N> x2( h );
std::cout << "Use case 2: " << x2.GetNum() << std::endl;
#endif
std::cout << "Hit the any key" << std::endl;
getchar();
return 0;
}
ここに CMakeLists.txt ファイルがあります
PROJECT(TestTemplateFunction)
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
FIND_PACKAGE( BOOST )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
ADD_EXECUTABLE( TestTemplateFunction main.cpp )
編集:コンパイルエラー
main.cpp(65) : error C2783: 'boost::shared_ptr<NH::Helper<TNumAtH,TSizeAtH>> NH::GetHelper(void)' : could not deduce template argument for 'TNumAtF'
main.cpp(44) : see declaration of 'NH::GetHelper'
main.cpp(65) : error C2783: 'boost::shared_ptr<NH::Helper<TNumAtH,TSizeAtH>> NH::GetHelper(void)' : could not deduce template argument for 'TSizeAtF'
main.cpp(44) : see declaration of 'NH::GetHelper'