我正在尝试实现以下代码的通用版本:
#include <iostream>
class ContainerA
{
public:
ContainerA( int newData )
: mData_(newData)
{}
int mData_;
};
class ContainerB
{
public:
ContainerB( int newData )
: mData_(newData)
{}
int mData_;
};
ContainerA staticInstanceA( 3 );
ContainerB staticInstanceB( 11 );
template< ContainerA* ptrToContainer >
class WorkerOnA
{
public:
WorkerOnA( )
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << mPtrToContainer_->mData_ << '\n';
}
private:
ContainerA* mPtrToContainer_;
};
template< ContainerB* ptrToContainer >
class WorkerOnB
{
public:
WorkerOnB( )
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << mPtrToContainer_->mData_ << '\n';
}
private:
ContainerB* mPtrToContainer_;
};
int main( )
{
WorkerOnA<&staticInstanceA> workerOnAInstance;
WorkerOnB<&staticInstanceB> workerOnBInstance;
workerOnAInstance();
workerOnBInstance();
return 0;
}
我想要的是(如果可能的话)是一个单独的Worker模板类,它可以被实例化以处理任何一个容器,如:
template< ?? ptrToContainer >
class WorkerOnAnyContainer
{
public:
WorkerOnA( )
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << mPtrToContainer_->mData_ << '\n';
}
private:
?? mPtrToContainer_;
};
然而,几个小时后,我仍然无法弄清楚应该是什么。也许模板向导有一个想法?
更新1 :修正了Workers的'operator()'中的错误(ptrToContainer - &gt; mPtrToContainer_)。对不起。
更新2 :我有一些工作,但如果有人有更好的想法,我仍然会很好奇。例如,拥有一个模板参数会很好。有谁知道“模板模板参数”在这种情况下是否有帮助?
template< class TContainer, TContainer* ptrToContainer >
class Worker
{
public:
Worker( )
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << mPtrToContainer_->mData_ << '\n';
}
private:
TContainer* mPtrToContainer_;
};
谢谢, d
答案 0 :(得分:3)
我会试一试。如何更改模板,以便将类型作为参数而不是指针本身?您仍然可以传入指向构造函数的指针:
template< typename TContainer >
class WorkerOnAnyContainer
{
public:
WorkerOnA( TContainer* ptrToContainer )
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << mPtrToContainer_->mData_ << '\n';
}
private:
TContainer* mPtrToContainer_;
};
然后你就可以使用它:
WorkerOnAnyContainer<ContainerA> workerOnAInstance(&staticInstanceA);
由于你想保留指针作为模板参数的设计,你可以选择这样的东西:
template< typename TContainer, TContainer* ptrToContainer >
class WorkerOnAnyContainer
{
public:
WorkerOnA()
: mPtrToContainer_(ptrToContainer)
{}
void operator()()
{
std::cout << "Data = " << ptrToContainer->mData_ << '\n';
}
private:
TContainer* mPtrToContainer_;
};
并使用它:
WorkerOnAnyContainer<ContainerA, &staticInstanceA> workerOnAInstance;
但是,这有点混乱,因为你需要两个模板参数,第一个感觉多余。我不确定用C ++ 03解决这个问题是可能的,但我认为可以构建一个可以在C ++ 11中为我们进行类型推导的辅助方法:
template<typename T>
auto CreateWorker(T* container) -> WorkerOnAnyContainer<T, container>
{
return WorkerOnAnyContainer<T, container>();
}
但是,由于编译器希望该函数适用于非编译时const参数,因此不能编译(GCC 4.6.3):
use of parameter 'container' outside function body
结果是you're not the only one trying to do this。显然,即使使用C ++ 11,也无法以这种方式创建辅助方法。
我能想到的唯一可行的方法就是使用宏(我知道,我知道):
#define CreateWorker(container) WorkerOnAnyContainer<decltype(container), &container>()
然后使用它就像:
auto worker = CreateWorker(staticInstanceA); // Note no `&'
这使用了auto
和一个简单的decltype
,这两个C ++ 11的功能都是英特尔C ++编译器从v12开始支持的(虽然我没有用GCC以外的任何东西测试过这个代码) 。作为一个宏观,它当然有点脆弱。