I’ve been trying to use CUDA from existing code base and encountered an internal compiler error. I’ve tried to reproduce context for the error which resulted in the following code.
#include <memory>
struct base {};
template <class base_t, class alloc_t, class...Args>
struct S :base_t
{
typedef typename std::allocator_traits<alloc_t>::template rebind_alloc<int> allocator_type;
//typedef typename trait<alloc_t>::template rebind<int> allocator_type; //okay
//typedef typename trait2<alloc_t>::template rebind<int> allocator_type; //okay. Here the same way of rebinding is used as in inpmlementation of MSVC's std::allocator_traits.
//typedef typename _Get_rebind_type<alloc_t, int>::type allocator_type; //okay
};
//template <class T> struct rebindable_type {};
template <class T>
using rebindable_type = std::allocator<T>;
int main(int, char**)
{
S<base, rebindable_type<char>, void> s;
return 0;
}
However, this error happens with std::allocator_traits for some reason. I even tried to copy-paste implementation of allocator_traits tо own implementation as specified below, but the resulting code cause no error. The corresponding code is commented out above, and the used classes are specified as follows. Helper elements used by trait2 are copy-pasted from MSVC xmemory0 header.
template <class T, class t, class Def>
typename T::template rebind<t>::other choose_def(int);
template <class T, class t, class Def>
Def choose_def(...);
template <class T> class trait {};
template <template <class> class C, class T> struct trait<C<T>>
{
template <class U>
using rebind = decltype(choose_def<C<T>, U, C<U>>(int()));
};
#define _GET_TYPE_OR_DEFAULT(TYPE, DEFAULT) \
{ \
template<class _Uty> \
static auto _Fn(int) \
-> _Identity<typename _Uty::TYPE>; \
\
template<class _Uty> \
static auto _Fn(_Wrap_int) \
-> _Identity<DEFAULT>; \
\
typedef decltype(_Fn<_Ty>(0)) _Decltype; \
typedef typename _Decltype::type type; \
}
template<class _Newfirst,
class _Ty>
struct _Replace_first_parameter;
template<class _Newfirst,
template<class, class...> class _Ty,
class _First,
class... _Rest>
struct _Replace_first_parameter<_Newfirst, _Ty<_First, _Rest...> >
{ // given _Ty<_First, _Rest...>, replace _First
typedef _Ty<_Newfirst, _Rest...> type;
};
template<class _Ty>
struct _Identity
{ // map _Ty to type unchanged, without operator()
typedef _Ty type;
};
struct _Wrap_int
{ // wraps int so that int argument is favored over _Wrap_int
_Wrap_int(int)
{ // do nothing
}
};
#define _COMMA ,
template<class _Ty,
class _Other>
struct _Get_rebind_type
_GET_TYPE_OR_DEFAULT(template rebind<_Other>::other,
typename _Replace_first_parameter<_Other _COMMA _Uty>::type);
template <class T> struct trait2
{
template <class U>
using rebind = typename _Get_rebind_type<T, U>::type;
};
I used CUDA 9.1 to compile this.
I apologize if this is the wrong place to post this, but it seems like it is an NVCC bug, but I am not sure.