与模板类交朋友:编译错误
我试图使用指向实现惯用语的指针来隐藏我正在使用 Concurrency::unbounded_buffer (来自 VC++ 2010)的事实。问题是,我正在使用模板执行此操作,但陷入了编译错误。代码如下:
BlockingQueue.h
#pragma once
namespace DRA{
namespace CommonCpp{
//Forward declaration
template <class Element> class BlockingQueueImpl;
template <class Element>
class BlockingQueue{
BlockingQueueImpl<Element>* m_pImpl;
//Forbid copy and assignment
BlockingQueue( const BlockingQueue& );
BlockingQueue& operator=( const BlockingQueue& );
public:
BlockingQueue();
~BlockingQueue();
void Push( Element newElement );
Element Pop();
};
}
}
BlockingQueue.cpp
#include "BlockingQueue.h"
#include "BlockingQueueImpl.h"
using namespace DRA::CommonCpp;
BlockingQueue<class Element>::BlockingQueue():
m_pImpl( new BlockingQueueImpl<Element>() ){
}
BlockingQueue<class Element>::~BlockingQueue(){
//Let the implementation's destructor handle pending Pops
delete m_pImpl;
}
template<class Element>
void BlockingQueue<Element>::Push( Element newElement ){
m_pImpl->Push( newElement );
}
template<class Element>
Element BlockingQueue<Element>::Pop(){
return m_Impl->Pop();
}
BlockingQueueImpl.h
#pragma once
#include <agents.h> //This is VS2010 Exclusive (Concurrency Runtime)
namespace DRA{ namespace CommonCpp{ template <class Element> class BlockingQueue; } }
namespace DRA{
namespace CommonCpp{
template <class Element>
class BlockingQueueImpl{
Concurrency::unbounded_buffer<Element> m_Queue;
//Only friends can use this class
friend class BlockingQueue<Element>;
BlockingQueueImpl();
~BlockingQueueImpl();
//Forbid copy and assignment
BlockingQueueImpl( const BlockingQueueImpl& );
BlockingQueueImpl& operator=( const BlockingQueueImpl& );
//Members
void Push( Element newElement );
Element Pop();
};
}
}
BlockingQueueImpl.cpp
#include "BlockingQueueImpl.h"
using namespace DRA::CommonCpp;
BlockingQueueImpl<class Element>::BlockingQueueImpl(){
}
BlockingQueueImpl<class Element>::~BlockingQueueImpl(){
}
template<class Element>
void BlockingQueueImpl<class Element>::Push( Element newElement ){
send( m_Queue, newElement );
}
template<class Element>
Element BlockingQueueImpl<class Element>::Pop(){
return receive( m_Queue );
}
错误是:
BlockingQueueImpl.cpp(12): error C2649: 'typename' : is not a 'class'
我尝试将类添加到友元声明中的模板参数中,但它不起作用
I'm trying to use the Pointer to Implementation Idiom to hide the fact that I am using a Concurrency::unbounded_buffer (from VC++ 2010). The problem is, I'm doing it with templates and got stuck in a compile error. Here's the code:
BlockingQueue.h
#pragma once
namespace DRA{
namespace CommonCpp{
//Forward declaration
template <class Element> class BlockingQueueImpl;
template <class Element>
class BlockingQueue{
BlockingQueueImpl<Element>* m_pImpl;
//Forbid copy and assignment
BlockingQueue( const BlockingQueue& );
BlockingQueue& operator=( const BlockingQueue& );
public:
BlockingQueue();
~BlockingQueue();
void Push( Element newElement );
Element Pop();
};
}
}
BlockingQueue.cpp
#include "BlockingQueue.h"
#include "BlockingQueueImpl.h"
using namespace DRA::CommonCpp;
BlockingQueue<class Element>::BlockingQueue():
m_pImpl( new BlockingQueueImpl<Element>() ){
}
BlockingQueue<class Element>::~BlockingQueue(){
//Let the implementation's destructor handle pending Pops
delete m_pImpl;
}
template<class Element>
void BlockingQueue<Element>::Push( Element newElement ){
m_pImpl->Push( newElement );
}
template<class Element>
Element BlockingQueue<Element>::Pop(){
return m_Impl->Pop();
}
BlockingQueueImpl.h
#pragma once
#include <agents.h> //This is VS2010 Exclusive (Concurrency Runtime)
namespace DRA{ namespace CommonCpp{ template <class Element> class BlockingQueue; } }
namespace DRA{
namespace CommonCpp{
template <class Element>
class BlockingQueueImpl{
Concurrency::unbounded_buffer<Element> m_Queue;
//Only friends can use this class
friend class BlockingQueue<Element>;
BlockingQueueImpl();
~BlockingQueueImpl();
//Forbid copy and assignment
BlockingQueueImpl( const BlockingQueueImpl& );
BlockingQueueImpl& operator=( const BlockingQueueImpl& );
//Members
void Push( Element newElement );
Element Pop();
};
}
}
BlockingQueueImpl.cpp
#include "BlockingQueueImpl.h"
using namespace DRA::CommonCpp;
BlockingQueueImpl<class Element>::BlockingQueueImpl(){
}
BlockingQueueImpl<class Element>::~BlockingQueueImpl(){
}
template<class Element>
void BlockingQueueImpl<class Element>::Push( Element newElement ){
send( m_Queue, newElement );
}
template<class Element>
Element BlockingQueueImpl<class Element>::Pop(){
return receive( m_Queue );
}
The error is:
BlockingQueueImpl.cpp(12): error C2649: 'typename' : is not a 'class'
I tried adding class to the template parameter in the friend declaration, but it didn't work
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除了现有答案之外:
我有相同的错误消息,但我的代码看起来略有不同:
这与现有答案中的情况相同:省略 class 关键字(编译器已经知道这是我假设的类型):
Addition to existing answer:
I had the same error message, but my code looked slightly different:
The same applies as in existing answer: Leave out class keyword (compiler already knows it's a type I'd assume):
您的问题是模板函数定义的语法不正确。应删除第二个
class
关键字。是的,您不应该将模板声明及其实现分开。
Your problem is incorrect syntax of the template function definition. The second
class
keyword should be removed.And yes, you should not separate template declaration and its implementation.
模板的特点是它们仅包含标题。您不能将模板实现放入 cpp 文件中,因为整个模板在实例化时需要可用。
我怀疑您是否可以在模板中使用这个习惯用法。
The thing with templates is that they are header-only. You can't put template implementations in the cpp files because the entire template needs to be available when it is instantiated.
I doubt you can use this idiom with templates at all.
模板基本上为编译器提供了构建代码的模板。它不是“真正的”代码,因为它可以按原样使用和编译。
这意味着当您实例化模板(在具有具体类类型的地方使用类或模板化方法)时,编译器需要查看实际的模板代码以生成正确的代码。
所有这些基本上意味着模板化代码必须位于标头中,并包含到使用模板化代码的任何其他文件中。
templates basically give a compiler a template to construct a code. It's not "real" code in the sense that it can be used and compiled as it.
This means that when you instantiate a template (use the class or templated method somewhere with a concrete class type) the compiler needs to see the actual template code to generate the right code.
What all this basically means is that the templated code MUST be in the headers, and included to any other file that uses the templated code.