Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有不使用模板的函数的模板类_C++_Templates_Static Libraries - Fatal编程技术网

C++ 具有不使用模板的函数的模板类

C++ 具有不使用模板的函数的模板类,c++,templates,static-libraries,C++,Templates,Static Libraries,为了减少遗传,我在跳圈 我读到一个类似的问题。它显示了如何使用基类解决问题。我试图摆脱继承,所以我在寻找一些不同的东西——更多的是沿着注释的路线 我创建并编译了一个专门的模板类(normal)。需要模板的方法位于标头(Mixer.hpp)中。不需要模板的方法位于cpp文件(Mixer.cpp)中。当编译到静态库中时,cpp部分仅编译为一个专门化(Mixer)。编译器当时不知道(awsome)。将生成的静态库导入另一个项目并尝试创建不同的泛型(awsome)类会导致链接器错误,因为库显然不包含该方

为了减少遗传,我在跳圈

我读到一个类似的问题。它显示了如何使用基类解决问题。我试图摆脱继承,所以我在寻找一些不同的东西——更多的是沿着注释的路线

我创建并编译了一个专门的模板类(
normal
)。需要模板的方法位于标头(
Mixer.hpp
)中。不需要模板的方法位于cpp文件(
Mixer.cpp
)中。当编译到静态库中时,cpp部分仅编译为一个专门化(
Mixer
)。编译器当时不知道(
awsome
)。将生成的静态库导入另一个项目并尝试创建不同的泛型(
awsome
)类会导致链接器错误,因为库显然不包含该方法标识符(
Mixer::noTemplateInvolved
)。但是,正常实现的代码与任何其他实现一样好,因此实际上链接器可以链接到其他模板版本的现有源(
Mixer::noTemplateInvolved
)。编译器所要做的就是为链接器适当地标记它

以下是导致链接器错误的源代码:

//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };

template<typename output = normal>
class Mixer
{
public:
    void callingTemplate();
    void noTemplateInvolved();
};

template<typename output>
void Mixer<output>::callingTemplate() { output::log(); }
//Mixer.cpp
#include "Mixer.hpp"
void Mixer<>::noTemplateInvolved()
{
    cout << "noTemplateInvolved\n";
}

//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")

struct awsome { static void log() { cout << "awsome\n"; } };

int main()
{
    Mixer<> n;
    n.callingTemplate();
    n.noTemplateInvolved();

    Mixer<awsome> a;
    a.callingTemplate();
    a.noTemplateInvolved(); //linker error here
    return 0;
}
//目标编译为Provider.lib
//混频器
#布拉格语一次
#包括
使用名称空间std;

struct normal{static void log(){cout答案是注释中建议的基类。我想要基类的原因之一是我不想重构。使用基类重构实际上非常简单

original
类重命名为
original\u base
。 继承自
original\u template
继承自
original\u base
。确保复制构造函数并将所有参数传递给基类。 使用original=original_template的语句
确保还不需要修改其他源代码

应用于上述示例,我最终做了如下操作:

//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };

class Mixer_Base
{
private:
    int mixcount;
public:
    Mixer_Base(int count);
    void noTemplateInvolved();
};

template<typename output = normal>
class Mixer_tempalte : public Mixer_Base
{
public:
    Mixer_tempalte(int count) : Mixer_Base(count)
    {}
    void callingTemplate();
};

template<typename output>
void Mixer_tempalte<output>::callingTemplate()
{
    output::log();
}

using Mixer = Mixer_tempalte<>;
//Mixer.cpp
#include "Mixer.hpp"

void Mixer_Base::noTemplateInvolved()
{
    cout << "noTemplateInvolved\n";
}

Mixer_Base::Mixer_Base(int count) : mixcount(count)
{}

//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")

struct awsome { static void log() { cout << "awsome\n"; } };

int main()
{
    Mixer n(4);
    n.callingTemplate();
    n.noTemplateInvolved();

    Mixer_tempalte<awsome> a(3);
    a.callingTemplate();
    a.noTemplateInvolved();
    return 0;
}
//目标编译为Provider.lib
//混频器
#布拉格语一次
#包括
使用名称空间std;

结构正常{静态无效日志(){如果它与模板无关,为什么它是一个成员,而且是一个非静态的呢?你可以将它作为一个单独的、非模板的非成员函数来实现,也许只有一个成员存根转发给它-你必须提供存根的定义,但它将只是一行最有可能是内联的。这是不是你在寻找什么?不管怎样,我不知道你为什么不想选择非依赖的基类解决方案;也许在问题中解释这个决定会让你的需求更清楚。你可以使用显式模板实例化。为什么你不想将非模板函数移到基类?它没有开销这种情况。最终目标是重构。如果我可以在标题中注释某些内容,我就不必触及实现。如果没有其他内容,这对我来说是有教育意义的。在本例中,显式实例化不起作用-库是在知道“struct awsome”之前编译的。我将尝试使用extern关键字,尽管我认为它是不受欢迎的在我的实际生产代码中,我开始使用基类,但是我有另一个想法,我将很快实现,看看这是否能让我更接近注释表单。