具有 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");
};
并且我将 float
和 double
专业化分为不同的 .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 而不是生成一个”。
最后,参数名称_D
为not allowed。 "如果程序员使用此类标识符,则行为未定义。"
所以我有一个 class 模板,例如
Template.h
template <typename T>
class Something {
public:
static_assert(std::is_floating_point<T>::value, "Floating Point only");
};
并且我将 float
和 double
专业化分为不同的 .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 而不是生成一个”。
最后,参数名称_D
为not allowed。 "如果程序员使用此类标识符,则行为未定义。"