简体   繁体   English

与模板成为朋友 class:编译错误

[英]Befriending a template class: Compile error

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).我正在尝试使用指向实现成语的指针来隐藏我正在使用 Concurrency::unbounded_buffer (来自 VC++ 2010)的事实。 The problem is, I'm doing it with templates and got stuck in a compile error.问题是,我正在使用模板执行此操作并陷入编译错误。 Here's the code:这是代码:

BlockingQueue.h阻塞队列.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阻塞队列.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阻塞队列Impl.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阻塞队列Impl.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我尝试将 class 添加到朋友声明中的模板参数中,但没有成功

Addition to existing answer:除了现有答案:

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

I had the same error message, but my code looked slightly different:我收到了相同的错误消息,但我的代码看起来略有不同:

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

The same applies as in existing answer : Leave out class keyword (compiler already knows it's a type I'd assume):现有答案相同:省略 class 关键字(编译器已经知道它是我假设的类型):

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

Your problem is incorrect syntax of the template function definition.您的问题是模板 function 定义的语法不正确。 The second class keyword should be removed.应删除第二个class关键字。

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

And yes, you should not separate template declaration and its implementation.是的,你不应该将模板声明和它的实现分开。

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.您不能将模板实现放在 cpp 文件中,因为整个模板在实例化时需要可用。

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.这意味着当您实例化模板时(在某处使用 class 类型的 class 或模板化方法),编译器需要查看实际的模板代码以生成正确的代码。

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.这一切基本上意味着模板化代码必须在标头中,并包含在使用模板化代码的任何其他文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM