2012-04-15 91 views
1

我想实现下面的代码的通用版本:指向全局实例的模板类作为模板参数?

#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; 
} 

我想有(如果这是可能的),是一个工人模板类,它可以被实例化工作在任一容器上,例如:

template< ?? ptrToContainer > 
class WorkerOnAnyContainer 
{ 
    public: 
     WorkerOnA() 
      : mPtrToContainer_(ptrToContainer) 
     {} 

     void operator()() 
     { 
      std::cout << "Data = " << mPtrToContainer_->mData_ << '\n'; 
     } 

    private: 
     ?? mPtrToContainer_; 
}; 

但是,几个小时后,我仍然无法确定'??'应该是什么。也许模板向导有一个想法?

更新1:修复了工人(ptrToContainer - > mPtrToContainer_)的'operator()'中的错误。对不起。

更新2:我得到了一些工作,但我仍然会好奇,如果任何人有更好的主意。例如,拥有一个模板参数会很好。有谁知道如果“模板模板参数”可以在这种情况下帮助吗?

template< class TContainer, TContainer* ptrToContainer > 
class Worker 
{ 
    public: 
     Worker() 
      : mPtrToContainer_(ptrToContainer) 
     {} 

     void operator()() 
     { 
      std::cout << "Data = " << mPtrToContainer_->mData_ << '\n'; 
     } 

    private: 
     TContainer* mPtrToContainer_; 
}; 

感谢, d

+1

哦,我看到我的编辑答案是多余,你的编辑:-)嗯。当你有一个接受模板参数的类型时,template-template参数是适用的,并且你使用该类型作为模板。我认为这不适用于此。我试着编写一个类型推断帮助函数,但是这不起作用,因为指针值是工作人员类型签名的一部分。 +1,这比我第一次想到的更有趣。 – Cameron 2012-04-15 18:43:19

+0

你使用C++ 11吗? – Cameron 2012-04-15 18:45:26

+0

@Cameron我的“生产”编译器是Intel的,它具有一些C++ 11功能:http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler/ 。组合模板参数需要哪些新功能? – Dragos 2012-04-15 19:06:38

回答

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特性都是Intel C++编译器在v12支持的特性(尽管我没有用除GCC之外的任何其他特性测试此代码)。作为一个宏,它当然有点脆弱。

See it in action!

+0

谢谢你的回复。事实上,这是我到目前为止所使用的。但是,这是更大数值模型的一部分,出于性能方面的原因,我现在要确保指向容器的指针在编译时嵌入到Worker中,以帮助编译器内联一些方法(在本例中省略)容器类,这是从工人调用的。还有什么想法? – Dragos 2012-04-15 16:49:51

+0

@Dragos:看我的编辑。希望能帮助到你! – Cameron 2012-04-15 18:34:18

+0

非常感谢您的回答!看来我们想出了相同的解决方案,但没有同步。你知道是否可以合并这两个模板参数?当然,这是一个侧面问题,但我认为这可能会让我的用户的生活更轻松:)。 – Dragos 2012-04-15 18:51:18

相关问题