模板化别名声明的部分特化
Partial specializations of templatized alias declarations
在 I am led to a particular solution which involves partial specializations of templatized alias declarations. The generic case is described in this answer。假设我有一个模板 class
template<typename T, ...>
class X {
// ....
};
我没有让 T 自由并专门化其他模板参数,而是处于其他参数依赖于 T 且仅依赖于 T 的情况。作为一个非常具体的例子(比另一个问题中的例子更易于管理)考虑一个模板 class
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
可能的专业是
Number_impl<int, std::abs>;
和
Number_impl<double, std::fabs>;
(我知道有重载的abs版本,这只是为了说明。如果你想看我的另一个例子)。
理想情况下,我想根据单个参数、类型定义一个模板 class Number,以便 Number 等于
Number_impl<int, std::abs>;
并且 Number 等于
Number_impl<double, std::fabs>;
类似于以下内容(不起作用):
template<typename T>
using Number = Number_impl<T, nullptr>;
template<>
using Number<int> = Number_impl<int, std::abs>;
template<>
using Number<double> = Number_impl<double, std::fabs>;
有谁知道这是否可行以及如何实现,或者如何以不同的方式实现相同的目标?
您可以添加一个图层:
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
template<typename T> struct Number_helper;
template<> struct Number_helper<int> { using type = Number_impl<int, std::abs>; };
template<> struct Number_helper<double> { using type = Number_impl<double, std::fabs>; };
template<typename T>
using Number = typename Number_helper<T>::type;
做这种事情的正常方法与标准库做它的方式相同 - 具有您可以专攻的特征 class:
#include <iostream>
#include <cmath>
template<typename T> struct NumberTraits;
template<typename T, class Traits = NumberTraits<T>>
class Number {
private:
T _t;
public:
Number(T t): _t(t) {}
T abs() const {
return Traits::abs(_t);
}
};
template<> struct NumberTraits<int>
{
static int abs(int i) {
return std::abs(i);
}
};
template<> struct NumberTraits<double>
{
static double abs(double i) {
return std::fabs(i);
}
};
using namespace std;
auto main() -> int
{
Number<int> a(-6);
Number<double> b(-8.4);
cout << a.abs() << ", " << b.abs() << endl;
return 0;
}
预期输出:
6, 8.4
在
template<typename T, ...>
class X {
// ....
};
我没有让 T 自由并专门化其他模板参数,而是处于其他参数依赖于 T 且仅依赖于 T 的情况。作为一个非常具体的例子(比另一个问题中的例子更易于管理)考虑一个模板 class
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
可能的专业是
Number_impl<int, std::abs>;
和
Number_impl<double, std::fabs>;
(我知道有重载的abs版本,这只是为了说明。如果你想看我的另一个例子)。
理想情况下,我想根据单个参数、类型定义一个模板 class Number,以便 Number
Number_impl<int, std::abs>;
并且 Number
Number_impl<double, std::fabs>;
类似于以下内容(不起作用):
template<typename T>
using Number = Number_impl<T, nullptr>;
template<>
using Number<int> = Number_impl<int, std::abs>;
template<>
using Number<double> = Number_impl<double, std::fabs>;
有谁知道这是否可行以及如何实现,或者如何以不同的方式实现相同的目标?
您可以添加一个图层:
template<typename T, T absVal(T)>
class Number_impl {
private:
T _t;
public:
Number_impl(T t): _t(t) {}
T abs() const {return absVal(_t);}
};
template<typename T> struct Number_helper;
template<> struct Number_helper<int> { using type = Number_impl<int, std::abs>; };
template<> struct Number_helper<double> { using type = Number_impl<double, std::fabs>; };
template<typename T>
using Number = typename Number_helper<T>::type;
做这种事情的正常方法与标准库做它的方式相同 - 具有您可以专攻的特征 class:
#include <iostream>
#include <cmath>
template<typename T> struct NumberTraits;
template<typename T, class Traits = NumberTraits<T>>
class Number {
private:
T _t;
public:
Number(T t): _t(t) {}
T abs() const {
return Traits::abs(_t);
}
};
template<> struct NumberTraits<int>
{
static int abs(int i) {
return std::abs(i);
}
};
template<> struct NumberTraits<double>
{
static double abs(double i) {
return std::fabs(i);
}
};
using namespace std;
auto main() -> int
{
Number<int> a(-6);
Number<double> b(-8.4);
cout << a.abs() << ", " << b.abs() << endl;
return 0;
}
预期输出:
6, 8.4