decltype 的另一个问题

发布于 2024-11-05 01:18:36 字数 1890 浏览 4 评论 0原文

//THIS IS JUST A FRAGMENT OF A static_numeric_limits.h for the purpose of this example   
 #include <limits.h>

    template<class T>
    struct static_numeric_limits;

    template<>
    struct static_numeric_limits<signed char>
    {/*min was outside of range for enum*/
        static const signed char min = SCHAR_MIN,
                                 max = SCHAR_MAX;
    };

    /*This "surplus" template is here for the reason that char is threated differently from signed char */
    template<>
    struct static_numeric_limits<char>
    {/*min was outside of range for enum*/
        static const char min = SCHAR_MIN,
                          max = SCHAR_MAX;
    };

    template<>
    struct static_numeric_limits<unsigned char>
    {
        static const unsigned char min = 0x0,
                             max = UCHAR_MAX;
    };
 ///REAL PROBLEM STARTS FROM HERE      
     template<class IntType,IntType low_range = static_numeric_limits<IntType>::min>
    struct Int
    {
        Int():value_(IntType())
        {}
        Int(const IntType& pattern)
        {
            value_ = (pattern);
        }
        constexpr inline IntType getValue()const
        {
            return value_;
        }
    private:
        IntType value_;
    };

    template<class IntType,class IntType_1>
    auto operator+
        (Int<IntType>& lhs, Int<IntType_1>& rhs)
        -> Int<decltype(lhs.getValue() + rhs.getValue())>//HERE IS THE PROBLEM
    {
        return lhs.getValue() + rhs.getValue();
    }

错误(来自 VS2010) 错误 C2027:使用未定义类型“static_numeric_limits
错误(来自 gcc 4.6)
错误:'decltype ((lhs->getValue() + rhs->getValue()))' 不是模板常量参数的有效类型

为什么这不像我想象的那样工作会吗?

//THIS IS JUST A FRAGMENT OF A static_numeric_limits.h for the purpose of this example   
 #include <limits.h>

    template<class T>
    struct static_numeric_limits;

    template<>
    struct static_numeric_limits<signed char>
    {/*min was outside of range for enum*/
        static const signed char min = SCHAR_MIN,
                                 max = SCHAR_MAX;
    };

    /*This "surplus" template is here for the reason that char is threated differently from signed char */
    template<>
    struct static_numeric_limits<char>
    {/*min was outside of range for enum*/
        static const char min = SCHAR_MIN,
                          max = SCHAR_MAX;
    };

    template<>
    struct static_numeric_limits<unsigned char>
    {
        static const unsigned char min = 0x0,
                             max = UCHAR_MAX;
    };
 ///REAL PROBLEM STARTS FROM HERE      
     template<class IntType,IntType low_range = static_numeric_limits<IntType>::min>
    struct Int
    {
        Int():value_(IntType())
        {}
        Int(const IntType& pattern)
        {
            value_ = (pattern);
        }
        constexpr inline IntType getValue()const
        {
            return value_;
        }
    private:
        IntType value_;
    };

    template<class IntType,class IntType_1>
    auto operator+
        (Int<IntType>& lhs, Int<IntType_1>& rhs)
        -> Int<decltype(lhs.getValue() + rhs.getValue())>//HERE IS THE PROBLEM
    {
        return lhs.getValue() + rhs.getValue();
    }

Error (from VS2010)
error C2027: use of undefined type 'static_numeric_limits<T>'
Error (from gcc 4.6)
error: 'decltype ((lhs->getValue() + rhs->getValue()))' is not a valid type for a template constant parameter

Why doesn't this work as I thought it would?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千秋岁 2024-11-12 01:18:40

这里的错误是 decltype 从表达式中推导出来的类型;不幸的是,错误消息并不清楚,这实际上是一个有点棘手的问题。

考虑表达式 0 + 0 的类型。是的,它是一个int,但更重要的是它是一个右值(非正式地,它是一个临时值)。这意味着 decltype(0 + 0) 不是 int,而是 int&&。现在考虑一下您的代码在这方面没有任何不同:您仍然有一个右值。

问题是模板非类型参数不能是右值引用,因此由于第二个参数的 type ,您不能使用 Int 。不过,您可以做的是:

#include <type_traits>

// ...

template <class IntType, class IntType_1>
auto operator+(const Int<IntType>& lhs, // be const-correct!
                const Int<IntType_1>& rhs)
                -> Int<typename std::remove_reference<
                        decltype(lhs.getValue() + rhs.getValue())>::type>
{
    return lhs.getValue() + rhs.getValue();
}

这会取消 int&& 的引用,为您提供裸露的 int 类型。希望 gcc 的错误消息更有意义:它试图告诉您不能将 int&& 用于非类型参数。


另一个问题(尽管可能不是问题)是整数算术经历所谓的 通常的算术转换。因此,将两个 Int 的值相加的结果实际上是一个 int,因此您的返回类型应该是 Int (并且是固定代码)。

那么,问题是您尚未定义 static_numeric_limits。但就像我说的,我怀疑这不是问题,你实际上已经定义了它,只是没有显示在你的问题中。

The error here is what type decltype is deducing from your expression; unfortunately the error messages aren't clear about it, and it's actually a bit of a tricky problem.

Consider the type of the expression 0 + 0. It's an int, yes, but more importantly it's an rvalue (informally, it's a temporary). This means that decltype(0 + 0) is not int, but int&&. Now consider that your code isn't any different, in this regard: you still have an rvalue.

The problem is that template non-type parameters cannot be rvalue references, so you cannot have Int<int&&>, because of the second parameter's type . What you can do, though is this:

#include <type_traits>

// ...

template <class IntType, class IntType_1>
auto operator+(const Int<IntType>& lhs, // be const-correct!
                const Int<IntType_1>& rhs)
                -> Int<typename std::remove_reference<
                        decltype(lhs.getValue() + rhs.getValue())>::type>
{
    return lhs.getValue() + rhs.getValue();
}

This takes the reference off int&&, giving you the bare int type. Hopefully gcc's error message makes a bit more sense: it's trying to tell you that you can't use int&& for your non-type parameter.


Another problem, though probably a non-issue, is that integer arithmetic undergoes what's called the usual arithmetic conversions. So the result of adding the values of two Int<char>'s is actually going to be an int, so your return type should be Int<int> (and is, with the fixed code).

The problem, then, is that you haven't defined static_numeric_limits<int>. But like I said, I suspect this is a non-issue and you do actually have it defined, just not displayed in your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文