Какой синтаксис я хочу достичь на стороне пользователя:
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 и wrapper, которые имеют статические члены, но статические члены нельзя назначать внешним переменным;
UPDATE:
Актуальной проблемой является равенство имен для общей структуры и специализированной структуры. Я не знаю, как заставить это работать без переименования:
// 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
};