Mal*_*lin 11 c++ templates explicit class specialization
在找到关于stackoverflow的许多问题的答案之后,我现在遇到了一个我无法找到答案的问题,我希望有人愿意帮助我!
我的问题是我想在C++中对一个类中的函数进行明确的模板化.我的编译器(g ++)和C++标准(§14.7.3)中的一个看起来告诉我,这个特化必须在声明类的命名空间中完成.我明白这意味着我不能把专业化放在课堂里,但是我没有看到这个限制的重点!有没有人知道是否有充分的理由不让专业在课堂上进行?
我知道有一些解决方法,例如将函数放在结构体中,但我想理解为什么语言有这种设计.如果有充分的理由不在课堂上允许专门的功能,我想在尝试解决它之前我应该知道它.
提前致谢!
为了让我的问题更加精确:以下是一些测试示例中的代码,说明了我想要做的事情:
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
execute<DIMENSIONALITY>();
};
private:
int privateVariable;
template <size_t currentDim>
static void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
static void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
};
Run Code Online (Sandbox Code Playgroud)
这是不可能的; g ++说:
SpecializationTest_fcn.h:27: error: explicit specialization in non-namespace scope ‘class MalinTester::SpecializationTest<DIMENSIONALITY>’
SpecializationTest_fcn.h:28: error: template-id ‘execute<0>’ in declaration of primary template
Run Code Online (Sandbox Code Playgroud)
如果我把函数执行到类外面,在名称空间MalinTester中,它将如下所示:
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY> class SpecializationTest {};
template <size_t currentDim>
void execute() {
printf("This is the general case. Current dim is %d. The private variable is %d.\n", currentDim, privateVariable);
execute<currentDim-1>();
}
template <>
void execute<0>() {
printf("This is the base case. Current dim is 0.\n");
}
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {};
virtual ~SpecializationTest() {};
void execute() {
MalinTester::execute<DIMENSIONALITY>();
};
private:
int privateVariable = 5;
};
};
};
Run Code Online (Sandbox Code Playgroud)
我不能在temp的templatized版本中使用privatevariable,因为它在类中是私有的.我真的希望它是私有的,因为我希望尽可能地封装我的数据.
当然,我可以送privateVariable作为参数的功能,但我认为这将是更美,以避免这一点,如果有一个很好的理由,C++标准不允许明确的专业化作为第一我真的不知道是上面的代码示例.
@Arne Mertz:这是我尝试过的解决方法,但它也不允许使用privateVariable.最重要的是,我想知道这样做是否是一个好主意.由于我不允许对成员函数进行专门化,也许我不应该对封装在类中的结构中的函数进行特化.
#include <cstdio>
namespace MalinTester {
template <size_t DIMENSIONALITY>
class SpecializationTest {
public:
SpecializationTest() {
privateVariable = 5;
};
virtual ~SpecializationTest() {};
void execute() {
Loop<DIMENSIONALITY, 0>::execute();
};
private:
int privateVariable;
template <size_t currentDim, size_t DUMMY>
struct Loop {
static void execute() {
printf("This is the general case. Current dim is %d.\n", currentDim);
Loop<currentDim-1, 0>::execute();
}
};
template <size_t DUMMY>
struct Loop<0, DUMMY> {
static void execute() {
printf("This is the base case. Current dim is 0.\n");
}
};
};
};
Run Code Online (Sandbox Code Playgroud)
基础专业:
在.h:
template <class T>
class UISelectorSlider : public UISelectorFromRange<T> {
public:
UISelectorSlider();
virtual ~UISelectorSlider();
private:
float width;
float getPositionFromValue(T value);
};
Run Code Online (Sandbox Code Playgroud)
在相同命名空间下的 .cpp 中:
template <>
float UISelectorSlider<MVHue>::getPositionFromValue(MVHue value)
{
return width * (float)value / 360.0;
}
Run Code Online (Sandbox Code Playgroud)
如果您想在专门的类中使用专门的功能:
内部类 add (.h)(私有函数):
private:
template <int I>
void foo();
Run Code Online (Sandbox Code Playgroud)
.cpp 内的专业化:
template <>
template <>
void UISelectorSlider<MVHue>::foo<3>()
{
// you can access private fields here
}
Run Code Online (Sandbox Code Playgroud)
更新:
但是你不能写这样的东西:
template <class T>
template <>
void UISelectorSlider<T>::foo<3>()
{
// you can access private fields here
}
Run Code Online (Sandbox Code Playgroud)
你会得到:错误:封闭的类模板没有明确专门化。
这个定义是在类内部还是在命名空间中无关紧要。关键是这不是完全的部分特化——这个函数没有定义上下文类(你想调用哪些成员)。换句话说 - 当您专门化成员时,您实际上尝试专门化整个包含类,而不是成员本身。编译器不能这样做,因为类尚未完全定义。所以这是模板设计的限制。如果它真的有效 - 模板将完全等同于简单的宏。(你可能会用一些宏魔法来解决你的任务。)