结交模板类:编译错误

Befriending a template class: Compile error

本文关键字:编译 错误      更新时间:2023-10-16

我试图使用指针实现习惯用法来隐藏我正在使用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'

我尝试在朋友声明中向模板参数添加class,但它不起作用

添加到现有答案:

error C2649: 'typename' : is not a 'class'

我有相同的错误信息,但我的代码看起来略有不同:

template< class T, class TNodeType = SimpleTreeNode<T> ...>
class Tree {
    friend class TNodeType; // *** Turns out: WRONG friend declaration

同样适用于现有的答案:省略class关键字(编译器已经知道它是我假设的类型):

template< class T, class TNodeType = SimpleTreeNode<T> ...>
class Tree {
    friend TNodeType; // *** OK: note missing `class`keyword

你的问题是模板函数定义的语法不正确。删除第二个class关键字

template<class Element>
void BlockingQueueImpl< /*class*/ Element>::Push( Element newElement ){
    send( m_Queue, newElement );
}

模板的问题是它们只有头信息。你不能把模板实现放在cpp文件中,因为整个模板需要在实例化时可用。

模板基本上是给编译器一个模板来构造代码。它不是"真正的"代码,因为它可以被使用和编译。
这意味着当你实例化一个模板(在某个地方使用类或模板化的方法和一个具体的类类型)时,编译器需要看到实际的模板代码来生成正确的代码。

所有这些基本上意味着模板化的代码必须在头文件中,并且包含在使用模板化代码的任何其他文件中。