История изменений
Исправление fsb4000, (текущая версия) :
Я надеюсь мне простят занудство, но в контексте решаемой ТС задачи действительно нужны шаблоны? Действительно это является наиболее рациональным решением?
Если нужно, чтобы метод f был не шаблонным, то можно перенести шаблон выше, но тогда нужно будет дублировать все остальные методы…
Как-то так: https://gcc.godbolt.org/z/vo77nez8c
В С++17, всё было бы проще из-за if constexpr
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr (has_double_multiply<T>(nullptr)) {
return x * y;
} else {
return x;
}
}
};
https://gcc.godbolt.org/z/es7vYnaMW
А в С++20 можно бы сделать так:
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr(requires{x*y;}) {
return x * y;
}
else {
return x;
}
}
};
https://gcc.godbolt.org/z/1on9bKfTK
Или так
template <typename T>
struct A {
T x{};
T f(double y) const requires(requires{x*y;}){
return x * y;
}
T f(double y) const requires(!requires{x*y;}){
return x;
}
};
https://gcc.godbolt.org/z/r78a5Kr47
В 14 плюсах всё было бы как в 11, но просто чуток короче:
Вместо:
template <typename U = T,
typename enable_if<!has_double_multiply<U>(nullptr), int>::type = 0>
U f(double /*y*/) const {
return x;
}
было бы
template <typename U = T, enable_if_t<!has_double_multiply_v<U>, int> = 0>
U f(double /*y*/) const {
return x;
}
https://gcc.godbolt.org/z/d39c8M9ax
И ещё одно :),
if constexpr
настолько лучше чем то что было раньше, что компиляторы ввели его для всех стандартов, https://gcc.godbolt.org/z/h94K58z44 , чтобы использовать для реализации стандартной библиотеки в режиме С++11/С++14 или С++98. А SFINAE/tag dispatch выжигать из исходников где только можно :)
Скоро и на концепты заменят где удобнее, как компиляторы немного обновятся:
Исправление fsb4000, :
Я надеюсь мне простят занудство, но в контексте решаемой ТС задачи действительно нужны шаблоны? Действительно это является наиболее рациональным решением?
Если нужно, чтобы метод f был не шаблонным, то можно перенести шаблон выше, но тогда нужно будет дублировать все остальные методы…
Как-то так: https://gcc.godbolt.org/z/vo77nez8c
В С++17, всё было бы проще из-за if constexpr
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr (has_double_multiply<T>(nullptr)) {
return x * y;
} else {
return x;
}
}
};
https://gcc.godbolt.org/z/es7vYnaMW
А в С++20 можно бы сделать так:
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr(requires{x*y;}) {
return x * y;
}
else {
return x;
}
}
};
https://gcc.godbolt.org/z/1on9bKfTK
Или так
template <typename T>
struct A {
T x{};
T f(double y) const requires(requires{x*y;}){
return x * y;
}
T f(double y) const requires(!requires{x*y;}){
return x;
}
};
https://gcc.godbolt.org/z/r78a5Kr47
В 14 плюсах всё было бы как в 11, но просто чуток короче:
Вместо:
template <typename U = T,
typename enable_if<!has_double_multiply<U>(nullptr), int>::type = 0>
U f(double /*y*/) const {
return x;
}
было бы
template <typename U = T, enable_if_t<!has_double_multiply_v<U>, int> = 0>
U f(double /*y*/) const {
return x;
}
Исправление fsb4000, :
Я надеюсь мне простят занудство, но в контексте решаемой ТС задачи действительно нужны шаблоны? Действительно это является наиболее рациональным решением?
Если нужно, чтобы метод f был не шаблонным, то можно перенести шаблон выше, но тогда нужно будет дублировать все остальные методы…
Как-то так: https://gcc.godbolt.org/z/vo77nez8c
В С++17, всё было бы проще из-за if constexpr
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr (has_double_multiply<T>(nullptr)) {
return x * y;
} else {
return x;
}
}
};
https://gcc.godbolt.org/z/es7vYnaMW
А в С++20 можно бы сделать так:
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr(requires{x*y;}) {
return x * y;
}
else {
return x;
}
}
};
https://gcc.godbolt.org/z/1on9bKfTK
Или так
template <typename T>
struct A {
T x{};
T f(double y) const requires(requires{x*y;}){
return x * y;
}
T f(double y) const requires(!requires{x*y;}){
return x;
}
};
Исходная версия fsb4000, :
Я надеюсь мне простят занудство, но в контексте решаемой ТС задачи действительно нужны шаблоны? Действительно это является наиболее рациональным решением?
Если нужно, чтобы метод f был не шаблонным, то можно перенести шаблон выше, но тогда нужно будет дублировать все остальные методы…
Как-то так: https://gcc.godbolt.org/z/vo77nez8c
В С++17, всё было бы проще из-за if constexpr
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr(has_double_multiply<T>(nullptr)) {
return x * y;
}
else {
return x;
}
}
};
https://gcc.godbolt.org/z/es7vYnaMW
А в С++20 можно бы сделать так:
template <typename T>
struct A {
T x{};
T f(double y) const {
if constexpr(requires{x*y;}) {
return x * y;
}
else {
return x;
}
}
};
https://gcc.godbolt.org/z/1on9bKfTK
Или так
template <typename T>
struct A {
T x{};
T f(double y) const requires(requires{x*y;}){
return x * y;
}
T f(double y) const requires(!requires{x*y;}){
return x;
}
};