0

我有两段代码:

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    
}

http://ideone.com/cXgnPy

和 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    
}

http://ideone.com/Rfs4Lv

第一种和第二种情况的错误有什么不同?哪个更好?

UPD:哪个“最小”实现更好?

4

3 回答 3

2

正如您的编译器可能告诉您的那样,问题在于operator<操作数的A和不匹配Aint内置了此运算符,但您需要为自己的类声明一个:

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中也有。<algorithm>

于 2013-09-02T07:33:37.667 回答
1

struct A 未定义 operator< 而 int 有

于 2013-09-02T07:25:39.980 回答
1

正如我在评论中所说:不要滥用 auto 关键字。您的函数min()比较相同类型的两个实例,因此完全没有理由使用尾随返回类型。返回类型是明确的T
第二个版本使用逗号运算符,它计算并丢弃第一个操作数,计算并返回第二个操作数。当您使用decltype表达式而不是实体时,如本例所示,它返回表达式的返回类型。所以这个版本返回T&而不是T.

所以答案是:第二个版本更好,因为避免了复制。但是这两个版本都是使用 triling return type 的糟糕且不必要的情况。好的方法是返回T

template<typename T>
T& min(const T& lhs , const T& rhs) 
{
    return lhs < rhs ? lhs : rhs;
} 
于 2013-09-02T07:47:50.103 回答