我有两段代码:
1)
template< class T >
auto min( T a, T b ) -> decltype(a)
{
return a < b ? a : b;
}
int main()
{
struct A{};
auto x = min( 2, 3 ) ;// success
auto a = A{};
auto b = A{};
auto c = min(a,b);// here is error
}
和 2)
template< class T >
auto min(T a, T b ) ->decltype(a<b, a)
{
return a < b ? a : b;
}
int main()
{
struct A{};
auto x = min( 2, 3 ) ;// success
auto a = A{};
auto b = A{};
auto c = min(a,b);// here is another error
}
有什么不同的第一和第二个案例错误?哪个更好?
UPD:'min'实施哪个更好?
答案 0 :(得分:2)
正如您的编译器可能告诉您的那样,问题是操作数operator<
和A
的{{1}}不匹配。 A
内置了此运算符,但您需要为自己的类声明一个:
int
然后struct A
{
A(int a) : a(a) {}
bool operator<(A const & rhs)
{
return a < rhs.a;
}
int a;
};
成为有效的通话。您提供的两个代码段的问题都是一样的。
哪个min(A(1), A(2))
实施更好?
我也不会选择。首先,不需要返回类型的延迟决定,你可以
min
并且第二个代码片段正在混淆相同的代码,这更糟糕。 template <typename T>
T min(T a, T b)
{ return a < b ? a : b; }
标题中还有std::min
。
答案 1 :(得分:1)
struct A不是运算符&lt;在int有
时定义答案 2 :(得分:1)
正如我在评论中所说:不要滥用自动关键字。您的函数min()
会比较两个相同类型的实例,因此根本没有理由使用尾随返回类型。返回类型显然是T
seond版本使用逗号运算符,该运算符计算并丢弃第一个操作数,并计算并返回第二个操作数。当您将decltype
与表达式而不是实体一起使用时,就像在这种情况下一样,它返回表达式的返回类型。因此,此版本返回T&
而不是T
。
所以答案是:第二个版本更好,因为避免了副本。但是这两个版本都是使用triling返回类型的不良和不必要的情况。好方法是返回T
:
template<typename T>
T& min(const T& lhs , const T& rhs)
{
return lhs < rhs ? lhs : rhs;
}