我正在尝试使用模板函数在模板类的构造函数中返回参数的默认值。函数的模板参数也是类的模板参数。我在下面提供了一个示例。
背景 该示例显示了确切的用例和依赖关系,因为它们也出现在我的应用程序中。X 类实际上是一个相当大的类,它管理一个大数据块,该大数据块被分成更小的块。Class Helper 是一个内存管理器,它分配和释放较小块大小的内存。实际上,GetHelper 函数会在运行时尝试推导出 Helper 的一些构造函数参数,所以这就是我使用这种设计的原因。
实际问题 当两个宏 USE_NS 和 SHOW_ERROR 都定义时,代码不会编译,在第 66 行给出错误 C2783 could not deduc template argument。这是我尝试使用模板函数 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'