The typedef template element is used in the raw parameter identifier in VS, but not in GCC

I am looking at some codes that make heavy use of templates. It compiles fine on GCC, but not on VS (tested for beta 2003–2010), where it does not work during parsing. Unfortunately, I don’t know the code structure enough to be able to reduce the problem and reproduce it in just a few lines, so I can only guess about the reason. I hope someone here can point me in the right direction.

We have

template< class UInt, typename IntT,
    bool is_signed = std::numeric_limits<IntT>::is_signed >
struct uii_ops_impl;

// ....

template<class UInt>
struct uii_ops_impl< UInt,
    typename make_signed<typename UInt::digit_type>::type, true >
{
    typedef UInt unbounded_int_type;
    typedef typename make_signed< typename unbounded_int_type::digit_type >::type
        integral_type;

    // ...

    static void add(unbounded_int_type& lhs, integral_type rhs);

    // ...
};

template<class UInt>
void uii_ops_impl<
    UInt, typename make_signed<typename UInt::digit_type>::type,
    true >::add(unbounded_int_type& lhs, integral_type rhs)
{
    // ....
}

When compiling on VS, the first error message (among many) returns

: error C2065: ' unbounded_int_type': undeclared identifier

I mean, point to typedef huh ?: -S

EDIT:

Something seems to be related to

typename make_signed<typename UInt::digit_type>::type

. typedefs, -, . , , , . make_signed - Boost.TypeTraits.

EDIT:

, , , , . ...

Bounty EDIT:

, , , , . . , . inline. . VS , std::allocator<void> size_type. , VS std::allocator<T> T = void, size_type. , size_type ?

, , VS , , ?

p.s. , , , VS, - Kevin Sopp mp_math Boost, libtommath.

+3
4

, .

  • unbounded_int_type - non-dependent ( 14.6.2.1)
  • . , -.

, Visual ++ , . - , -. , .

template<class UInt>
void uii_ops_impl<
    UInt, typename make_signed<typename UInt::digit_type>::type,
    true >::add(typename
                /* repeat-that-beast uii_ops...true> here */
                   ::unbounded_int_type& lhs, 
                typename /* and here too */::integral_type rhs)
{
    // ....
}
+6

- -

MSVC, , , , typedef .

, , ( ). , , , ( make_signed<>, make_signed<>::type ).

+1

?

unbounded_int_type :

template<class UInt>
void uii_ops_impl<
    UInt, typename make_signed<typename UInt::digit_type>::type,
    true >::add(unbounded_int_type& lhs, integral_type rhs)
{
    // ....
}

:

template<class UInt>
void uii_ops_impl<
    UInt, typename make_signed<typename UInt::digit_type>::type,
    true >::add(uii_ops_impl<UInt, etc ,true>::unbounded_int_type& lhs, integral_type rhs)
{
    // ....
}

?

0

. typename, , .

, , unbounded_int_type::digit_type - ? unbounded_int_type. , , typename.

template< class UInt, typename IntT,
bool is_signed = std::numeric_limits<IntT>::is_signed >
struct uii_ops_impl;

// ....

template <class T>
struct make_signed
{
    typedef T type;
};

template<class UInt>
struct uii_ops_impl< UInt,
    typename make_signed<typename UInt::digit_type>::type, true >
{
    typedef UInt unbounded_int_type;
    typedef typename make_signed< typename unbounded_int_type::digit_type >::type
        integral_type;

    // ...

    static void add(unbounded_int_type& lhs, integral_type rhs);

    // ...
};

template<class UInt>
void uii_ops_impl<
UInt, typename make_signed<typename UInt::digit_type>::type,
true >::add(unbounded_int_type& lhs, integral_type rhs)
{
    // ....
}

The only change here is I added a keyword typename.

typedef
typename make_signed < typename unbounded_int_type :: digit_type> :: type integral_type;
0
source

Source: https://habr.com/ru/post/1715027/


All Articles