部分特化的默认参数
我想在用户端实现什么语法:
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和具有静态成员的包装类,但静态成员可以' t 被分配给外部变量;
更新: 实际问题是通用结构和专用结构的名称相等。我不知道如何在不重命名的情况下使其工作:
// 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
};
What syntax I want to achieve on user side:
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
What implementation for this I have now (not working because default parameters for partial specialization are not allowed):
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
};
I've tried with enable_if and wrapper classes that have static members, but static members can't be assigned to extern variables;
UPDATE:
The actual problem is name equality for general struct and specialized struct. I don't know how to make it work without renaming:
// 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
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不知道为什么你认为这是有道理的
你无法完成这项工作:模板参数不能是
double
类型的值(它们可以是double
类型的左值,但你的模板需要一个double
的地址,所以这是关闭的)。您可以使用函数模板来使语法正常工作。
或者,如果您准备进行一些丑陋的黑客攻击,则可以使用类模板。
如果您提供两个参数,则不会使用默认参数。如果您仅提供
,则将使用默认参数并起作用。如果您只提供
,默认参数也会被使用,但不起作用。I don't know why you think that this make sense
You cannot make this work: Template arguments cannot be values of type
double
(they can be an lvalue of typedouble
, but your template requires the address of adouble
, so that's off).You can use function templates to make your syntax work
Alternatively, you can use class templates if you are up for some ugly hacks
The default argument will not be used if you provide both arguments. If you provide only
<double>
, the default argument will be used and will work. If you only provide<float>
, the default argument will be used too, but will not work.您需要更改拥有比较运算符的结构,以便可以专门化外部模板,请参阅:http://ideone.com /xqtjz
代码是:
You need to change the structure which owns the comparison operator such that you can specialize the outer template, see: http://ideone.com/xqtjz
the code is:
我会采用类似特征的方法:
然后当需要特定的 epsilon 时:
并使用它:
I would go with traits-like approach:
and then when specific epsilon is needed:
and use it: