我正在尝试使用Pointer to Implementation Idiom来隐藏我使用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'
我尝试将类添加到friend声明中的template参数,但它不起作用
答案 0 :(得分:4)
除现有答案外:
error C2649: 'typename' : is not a 'class'
我有相同的错误消息,但我的代码看起来略有不同:
template< class T, class TNodeType = SimpleTreeNode<T> ...>
class Tree {
friend class TNodeType; // *** Turns out: WRONG friend declaration
同样适用于existing answer:省略类关键字(编译器已经知道它是类型I&#39;假设):
template< class T, class TNodeType = SimpleTreeNode<T> ...>
class Tree {
friend TNodeType; // *** OK: note missing `class`keyword
答案 1 :(得分:3)
您的问题是模板函数定义的语法不正确。应删除第二个class
关键字。
template<class Element>
void BlockingQueueImpl< /*class*/ Element>::Push( Element newElement ){
send( m_Queue, newElement );
}
是的,你不应该分开模板声明及其实现。
答案 2 :(得分:1)
模板的东西是它们只是标题。您不能将模板实现放在cpp文件中,因为整个模板在实例化时需要可用。
我怀疑你可以将这个习惯用于模板。
答案 3 :(得分:1)
模板基本上为编译器提供了构建代码的模板。它不是真实的&#34;代码,因为它可以像它一样使用和编译 这意味着当您实例化模板(使用具有特定类类型的某个类或模板化方法)时,编译器需要查看实际的模板代码以生成正确的代码。
这一切基本上意味着模板化代码必须位于标题中,并包含在使用模板化代码的任何其他文件中。