PTS*_*PTS 3 c++ templates c++11
我发现了几个类似问题的问题,但找不到针对我特殊情况的直接答案。模板的整个语法让我非常困惑,因此我可能会误解了一些东西。
我有一个应该接受每种类型的类模板。简单的例子:
template <class T>
class State {
public:
void set(T newState);
T get();
private:
T state;
};
template <class T>
void State<T>::set(T newState){
state = newState;
}
template <class T>
T State<T>::get(){
return state;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想为一组类型提供一个专门的模板,为这些类型添加一个附加功能。从到目前为止的发现,我可以利用所谓的type_traits,但是如何精确地使用它们来实现这一点对我来说仍然是一个谜。
如果有这种针对int类型的专业化,但是我不想允许所有其他int和float变体,而不是只为int类型编写这种特性。我找到了std :: is_arithmetic,但不知道如何利用它来实现这一目标。
template <>
class State <int> {
public:
void set(int newState);
int get();
int multiplyState(int n);
private:
int state;
};
void State<int>::set(int newState){
state = newState;
}
int State<int>::get(){
return state;
}
int State<int>::multiplyState(int n){
return state*n;
}
Run Code Online (Sandbox Code Playgroud)
您可以将部分模板专业化与SFINAE结合使用以实现以下目的:
#include <type_traits>
template <class T, typename = void>
class State
{
T state;
public:
void set(T newState)
{
state = newState;
}
T get()
{
return state;
}
};
template <typename T>
class State<T, std::enable_if_t<std::is_arithmetic_v<T>>>
{
T state;
public:
void set(int newState)
{
state = newState;
}
int get()
{
return state;
}
int multiplyState(int n)
{
return state*n;
}
};
Run Code Online (Sandbox Code Playgroud)
这里的窍门在于使用第二个模板参数(可以不命名,并使用默认参数)。当您使用类模板的特殊化时,例如,,State<some_type>编译器必须弄清楚应该使用哪个模板。为此,它必须以某种方式将给定的模板参数与每个模板进行比较,并确定最匹配的模板参数。
实际完成此匹配的方法是,尝试从给定的模板参数中推断出每个局部专业化的参数。例如,在的情况下State<int>,模板参数将为intand void(后者是存在的,因为主模板的第二个参数的默认参数)。然后,我们尝试为我们唯一的局部专业化推论
template <typename T>
class State<T, std::enable_if_t<std::is_arithmetic_v<T>>>;
Run Code Online (Sandbox Code Playgroud)
从模板参数开始int, void。我们的部分专业化具有单个参数T,可以直接从第一个模板参数be推导出int。至此,我们已经完成了所有参数的推导(这里只有一个)。现在,我们将推导的参数代入部分专业化:中State<T, std::enable_if_t<std::is_arithmetic_v<T>>>。我们最后得到State<int, void>,它与的初始参数列表匹配int, void。因此,部分模板专业化适用。
现在,如果相反,我们写了State<some_type>,这里some_type不是一个算术类型,那么该过程将是相同的最高的地方,我们已经成功地推导出的参数部分特是点some_type。同样,我们将参数代入部分专业化State<T, std::enable_if_t<std::is_arithmetic_v<T>>>。但是,std::is_arithmetic_v<some_type>现在将是false,这将导致std::enable_if_t<…>未定义并且替换失败。由于在这种情况下替换失败不是错误,因此这仅意味着部分专业化不是此处的选择,而是将使用主模板。
如果存在多个匹配的局部专业,则必须对它们进行排名以选择最佳匹配。实际的过程非常复杂,但是通常归结为选择最具体的专业。
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |