我试图了解新的c ++功能,并提出了max函数的实现:
#include <utility>
template <typename T>
concept bool Comparable() {
return requires(T a, T b)
{
{a > b} -> bool;
{a < b} -> bool;
{a >= b} -> bool;
{a <= b} -> bool;
};
}
template<Comparable T, Comparable U>
constexpr decltype(auto) max(T&& a, U&& b)
{
return std::forward<T>(a) > std::forward<U>(b) ? std::forward<T>(a) : std::forward<U>(b);
}
int main()
{
constexpr int a = 2, b = 3;
return max(a, b);
}
这可以代替宏版本吗?
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
如果没有可以改进的地方?
我正在使用gcc-8.1.0
和-std=c++2a
,-fconcepts
和-O3
标志进行编译
感谢您的建议,现在的样子是这样:
#include <utility>
template<typename T, typename U>
concept bool TypesLessComparable() {
return requires(T a, U b)
{
{a < b} -> bool;
};
}
template<typename T, typename U>
constexpr decltype(auto) max(T&& a, U&& b) requires (TypesLessComparable<T, U>() == true)
{
return a < b ? std::forward<U>(b) : std::forward<T>(a);
}
int main()
{
constexpr int a = 2, b = 3;
return max(a, b);
}
答案 0 :(得分:3)
这个max函数不错吗?
否,至少有3个问题:
1不清楚为什么在函数仅需要其中一个的情况下为何请求多个比较操作(仅使用class
的情况下,operator>
仅用于定义max()
)< / p>
2概念Comparable
要求类型本身具有比较操作,您可以比较2个不同类型的对象。这会使概念的使用无效(函数应仅使用概念所要求/提供的内容)
3您也可以返回不同类型的对象,一个对象可以转换为另一个对象,但是您应该用另一个概念来覆盖它。
这是情况2和3的代码示例:
struct A { friend bool operator>( const A&, const A& ); };
struct B { friend bool operator>( const B&, const B& ); };
auto x = max( A(), B() );
总结:
您的函数应该要求对类型进行最少的操作,这是操作所必需的。
如果类型通过了概念验证,则您的函数应该可以成功编译。
这可能不是全部要求。
答案 1 :(得分:3)
std::forward<T>(a) > std::forward<U>(b) ? std::forward<T>(a) : std::forward<U>(b);
您将结果转发两次。对于大多数类型,这是错误的(对于将移动作为深层副本实现的类型,只有确定)。您应该从比较中删除正向。