防止c++模板代码被多次编译

问题描述 投票:0回答:1

我用c++编写了一个消息队列模板,我想在许多不同的项目中使用它,所以我将它放入一个命名空间中,例如

my_lib

为了防止代码被重复编译,我使用了一个单独的trans-unit来显式实例化它(并且只得到一个obj文件),并且只在涉及它的地方包含它的头。

但是使用它的地方是在另一个命名空间中,例如

business

我的代码框架如下所示:

mq-template.hpp:

#pragma once
namespace my_lib {
template<typename T, typename SIZE_TYPE>
class GenericMQ_t {
    struct Node_t {
        SIZE_TYPE _head;
        SIZE_TYPE _tail;
        T         _data;
    };
    SIZE_TYPE _size {};
    Node_t*   _buff {};
public:
    void send( const T& );
};
}; // namespace my_lib

mq-template.tpp(注意后缀):

#include "mq-template.hpp"
namespace my_lib {
template<typename T, typename SIZE_TYPE>
void GenericMQ_t<T, SIZE_TYPE>::send( const T& ) {
    // just for example
    std::cout << "Hello!";
};
}; // namespace my_lib

mq-instance.hpp:

#pragma once
#include "mq-template.hpp"
namespace business {
struct Msg_t {};
using RealMQ_t = my_lib::GenericMQ_t<Msg_t, int>;
}; // namespace business

mq-instance.cpp:

#include "mq-instance.hpp"
#include "mq-template.tpp"
namespace business {
template class my_lib::GenericMQ_t<Msg_t, int>;
}; // namespace business

main.cpp:

#include "mq-instance.hpp"
int main() {
    business::Msg_t    msg;
    business::RealMQ_t mq;
    mq.send( msg );
    return 0;
}

mq-instance.cpp
编译时,我遇到了这样的错误:

命名空间“business”中“class my_lib::GenericMQ_t”的显式实例化(不包含命名空间 'my_lib') [-fpermissive]

'struct 的显式实例化 命名空间中的 my_lib::GenericMQ_t::Node_t' 'business'(不包含命名空间'my_lib')[-fpermissive]

不可能将我的所有代码放入同一个命名空间中,因为它们属于不同的项目,并且即使在同一个项目中,命名模式也可能是分层的。

我应该如何修改我的代码,让它同时满足:

  1. 模板代码不宜多次编译;
  2. 模板代码和实例化代码可能位于不同的位置 命名空间;

抱歉我的英语不好。

c++ templates namespaces explicit-instantiation translation-unit
1个回答
0
投票

您可以将显式实例化移动到封闭名称空间(即全局名称空间),如下所示。

mq-instance.cpp

#include "mq-instance.hpp"
#include "mq-template.tpp"

template class my_lib::GenericMQ_t<business::Msg_t, int>; //in global namespace
namespace business {  

};

工作演示

© www.soinside.com 2019 - 2024. All rights reserved.