部分专门化的默认参数
Default parameter for partial specialization
我想在用户端实现什么语法:
double a(1.), b(2.), deps(.1);
bool res1 = compare<double>()(a, b); // works with default eps
bool res2 = compare<double, &deps>()(a, b); // works with explicitly provided eps
float c(1.), d(1.). feps(.1);
bool res3 = compare<float>()(c, d); // don't have default eps - must not compile
bool res4 = compare<float, &feps>()(c, d); // works only with provided eps
我现在有什么实现(不工作,因为部分专门化的默认参数是不允许的):
extern double eps_double; // somewhere defined and initialized
template<typename T, const T* eps>
struct compare { // actually inherits std::binary_function
bool operator()(const T& t1, const T& t2) {
return t1 < t2 - *eps;
}
};
template<const double* eps = &eps_double>
struct compare<double, eps> { // the same as in default implementation
};
我已经尝试与enable_if和包装类的静态成员,但静态成员不能分配给外部变量;
更新:实际问题是一般结构体和专门化结构体的名称相等。如果不重命名,我不知道如何使它工作:
// treats all explicitly passed eps and don't need default parameter
template<typename T, const T* eps>
struct compare_eps { // need another name!
bool operator()(const T& t1, const T& t2) {
return t1 < t2 - *eps;
}
};
// don't need default parameter either
// because we always know what eps to use for a concrete type
template<typename T>
struct compare {
// define nothing -> will not compile on types we don't have specialization for
};
template<>
struct compare<double> {
// use here eps_double hardcoded
};
我不知道你为什么认为这有意义
compare<double, deps>
你不能这样做:模板参数不能是类型为double
的值(它们可以是类型为double
的左值,但你的模板需要double
的地址,所以这是关闭的)。
你可以使用函数模板来使你的语法工作
extern double eps_double;
template<typename T>
types::compare<T, &eps_double> compare(
typename enable_if<is_same<T, double>>::type * = 0
) {
return types::compare<T, &eps_double>();
}
template<typename T, const T *eps>
types::compare<T, eps> compare() {
return types::compare<T, eps>();
}
或者,你可以使用类模板,如果你准备一些丑陋的hack
template<typename T, const T* eps = &eps_double>
struct compare {
bool operator()(const T& t1, const T& t2) {
return t1 < t2 - *eps;
}
};
如果同时提供两个参数,则不会使用默认参数。如果只提供<double>
,则将使用默认参数并正常工作。如果您只提供<float>
,则也将使用默认参数,但将不起作用。
您需要更改拥有比较操作符的结构,以便您可以专门化外部模板,参见:http://ideone.com/xqtjz
代码是:
extern double eps_double; // somewhere defined and initialized
extern double deps; // NOTE: you have to make these extern a well, else cannot work
extern float feps;
template<typename T>
struct compare {
// this internal structure now has the operator()
template <const T* eps>
struct it
{
bool operator()(const T& t1, const T& t2) const {
return t1 < t2 - *eps;
}
};
};
// specialize compare for double
template<>
struct compare<double>
{
// here you can provide the default
template<const double* eps=&eps_double>
struct it
{
bool operator()(const double& t1, const double& t2)
{
return t1 < t2 - *eps;
}
};
};
int main(void)
{
double a(1.), b(2.);
bool res1 = compare<double>::it<>()(a, b); // works with default eps
bool res2 = compare<double>::it<&deps>()(a, b); // works with explicitly provided eps
float c(1.), d(1.);
bool res3 = compare<float>::it<>()(c, d); // don't have default eps - will not compile
bool res4 = compare<float>::it<&feps>()(c, d); // works only with provided eps
}
我会采用类似特性的方法:
template<class T>
struct DefaultEps;
template<>
struct DefaultEps<double>
{
static const double eps = 4.0;
};
// may or may not be needed in .cpp
// const double DefaultEps<double>::eps;
template<>
struct DefaultEps<float>
{
static const float eps = 4.0;
};
// may or may not be needed in .cpp
// const float DefaultEps<float>::eps;
template<class T, class E = DefaultEps<T> >
struct Compare
{
bool operator()(T const &t1, T const &t2)
{
return(t1 < t2 - E::eps);
}
};
然后当需要特定的epsilon时:
struct SpecificEps
{
static const float eps = 4.0;
};
// may or may not be needed in .cpp
// const float SpecificEps::eps;
并使用:
Compare<float, SpecificEps>()(...);
相关文章:
- 如何使用默认参数等选择模板专业化
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 何时提供默认参数作为模板参数
- 将const引用参数初始化为默认参数会导致悬空引用吗
- 如何修复带有 clang 的参数'args'缺少默认参数的问题?
- 函数不接受 X 参数,函数使用默认参数
- initializer_list具有默认参数的构造函数
- C++ 带有默认参数的结构,可选择在构造函数中更改
- 为什么C++构造函数在继承中需要默认参数?
- 必须非常量别名参数及其默认参数常量
- C++ 默认参数使用其他参数
- 组合函数参数包和默认参数
- 如何定义 Vector2f 的默认参数?[SFML]
- 有条件地将默认参数传递给函数(使用"?"运算符)
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- 如何设置默认参数以防用户不输入另一个参数
- 结构 c++ 中的默认参数
- 构造函数委托与默认参数
- 默认参数和函数指针作为函数参数C++
- 如何在继承层次结构中调用具有默认参数的构造函数?