0

所以我有一个类模板,例如

模板.h

template <typename T>
class Something {
public:

    static_assert(std::is_floating_point<T>::value, "Floating Point only");
};

我将floatdouble专业化分成不同的 .h 文件

浮动.h

#include "Template.h"

template<>
class Something<float> {
public:

    std::string Name = "Float";

    void DoSomething() {
        std::cout << "Float Thing\n";
    }
};

双倍.h

#include "Template.h"

template<>
class Something<float> {
public:

    std::string Name = "Double";

    void DoSomething() {
        std::cout << "Double Thing\n";
    }
};

我在我的文件中按顺序包含了这三个文件.cpp,它工作正常

但我需要向float以Something作为参数的专业化添加另一个函数

void SayDouble(Something<double> _D) {
    std::cout << _D.Name << '\n';
}

然后包含Double.haftertemplate.h并且它可以工作,但是当我尝试在其中执行相同操作Double.h并添加一个接受或返回Something<float>并包含float.hafter的函数时tempalte.h。它给了我很多关于重新实例化的错误

 Float.h(17,19): error C2039: 'Name': is not a member of 'Something<double>'
1>Float.h(16): message : see declaration of 'Something<double>'
1>Double.h(7,1): error C2908: explicit specialization; 'Something<double>' has already been instantiated
1>Double.h(19,2): error C2766: explicit specialization; 'Something<double>' has already been defined
1>Float.h(16): message : see previous definition of 'Something<double>'
1>Float.h(19,2): error C2766: explicit specialization; 'Something<float>' has already been defined
1>Float.h(7): message : see previous definition of 'Something<float>

我不太明白我猜想的问题是,可能在函数签名中对模板进行专门化会实例化模板,然后当它尝试在定义中再次实例化它时,它给出“已定义错误”但我不不知道如何解决这个问题,因为我需要有引用其他专业的函数

我正在使用 Visual Studio Community 2019 版本 16.11.6

4

1 回答 1

0

显式特化是一个独特的类,根本不必类似于原始模板。您可以更改功能,制作完全不同的功能或其他任何功能。

这通常是部分专业化的点,因此 aconst T可以是与计划T等不同的接口。

任何显式特化都必须在使用该特化之前声明。这就是您收到重新声明错误的原因。

另外,您显示<float>了两次,我认为这是粘贴错误?Double.h 中的那个应该是对的<double>吧?

您的循环引用违反了这一点。您可以通过声明您需要的(不定义它)来解决这个问题,类似于您使用相互递归函数的方式。

这是正确编译和运行的代码: https ://godbolt.org/z/x1TcTE7Me

你会注意到

//template<>      // Don't use the `template<>` prefix here!!!
inline void Something<float>::SayDouble(Something<double> p_D) {
        std::cout << p_D.Name << '\n';
    }
// I'm showing it with `inline` in case you put it in a header.  It can go in
// some CPP file though, as it's been declared in the class specialization.

使用template前缀。这是因为这是为一个类定义一个成员函数(不是模板),就像普通类一样——显式(而不是部分)特化是像任何其他类一样的普通类,而不是模板。它只是说“当我要求该模板的这种专业化时,使用这个类而不是生成一个”。

最后,参数名称_D不允许的。"如果程序员使用此类标识符,则行为未定义。 "

于 2021-11-22T20:32:11.600 回答