views:

103

answers:

1

I can't compile yaml-cpp in RAD Studio 2010. I have error in nodeutil.h

template <typename T, typename U>
struct is_same_type {
enum { value = false };
};

template <typename T>
struct is_same_type<T, T> {
enum { value = true };
};

template <typename T, bool check>
struct is_index_type_with_check {
enum { value = false };
};

template <> struct is_index_type_with_check<std::size_t, false> 
    { enum { value = true }; }; // line 24

#define MAKE_INDEX_TYPE(Type) \
template <> struct is_index_type_with_check<Type, is_same_type<Type, std::size_t>::value> { enum { value = true }; }

MAKE_INDEX_TYPE(int);
MAKE_INDEX_TYPE(unsigned); // line 30
MAKE_INDEX_TYPE(short);
MAKE_INDEX_TYPE(unsigned short);
MAKE_INDEX_TYPE(long);
MAKE_INDEX_TYPE(unsigned long);
#undef MAKE_INDEX_TYPE

Compiler print:

[BCC32 Error] nodeutil.h(30): E2238 Multiple declaration for 'is_index_type_with_check<unsigned int,0>'

[BCC32 Error] nodeutil.h(24): E2344 Earlier declaration of 'is_index_type_with_check<unsigned int,0>'

I think that all correct - in line 24 I got

is_index_type_with_check<std::size_t, false>,

in line 30 I got

is_index_type_with_check<unsigned, true>.

Two different type.

But if I change line 24 like below, RAD Studio can compile yaml-cpp

template <> struct is_index_type_with_check<std::size_t, true> { enum { value = true }; }; // false -> true

Why?! In line 24 I got

is_index_type_with_check<std::size_t, true>

and in line 30

is_index_type_with_check<unsigned, true>

Two identically type. But all work in RAD Studio and doesn't in MS VS 2008 Express.

A: 

Trying out your code with CodeBlocks, the problems showed exactly vice versa. This means, that my code compiles with

template <> struct is_index_type_with_check<std::size_t, false>

and fails with

template <> struct is_index_type_with_check<std::size_t, true>

in line 24.

The problem seems to be, which types compilers think are the same and which are different. This problem spreads over different phases of the compile process. Look again at your compiler error. The template arguments of is_index_type_with_check are the same for both std::size_t and unsigned. That means, that your compiler thought that std::size_t and unsigned are different types for template argument deduction (is_same_type::value == false), but the type deduction later found std::size_t and unsigned to be of the same type unsigend int and complains with an error.

So to sum up you didn't read your compiler error correctly - MAKE_INDEX_TYPE(unsigned); created an is_index_type_with_check<unsigned int, false>. That type clashed with your template <> struct is_index_type_with_check<std::size_t, false> and the compiler complained.

ablaeul