具有 class 模板的不同专业化,并且专业化定义在其签名中具有与其他专业化的功能

Having different specialization of a class template and the specialization definitions have functions with other specializations in its signature

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

Template.h

template <typename T>
class Something {
public:

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

并且我将 floatdouble 专业化分为不同的 .h 文件

float.h

#include "Template.h"

template<>
class Something<float> {
public:

    std::string Name = "Float";

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

Double.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';
}

然后在 template.h 之后包含 Double.h 并且它有效但是当我尝试在 Double.h 中做同样的事情并添加一个函数时 returns Something<float> 并在 tempalte.h 之后包含 float.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

显式特化是一种独特的 class,完全不必与原始模板相似。您可以更改功能,制作完全不同的功能,或其他任何方式。

这通常是部分专业化的重点,因此 const 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前缀。那是因为这是为 class 定义一个成员函数(不是模板),就像普通的 class 一样——显式(而不是部分)特化是一个普通的 class 就像任何其他,不是模板。它只是说“当我要求该模板的这种专业化时,使用这个 class 而不是生成一个”。

最后,参数名称_Dnot allowed。 "如果程序员使用此类标识符,则行为未定义。"