2

Given this snippet:

template <std::size_t Index, typename T, typename ...Args>
typename type_at<Index, T, Args...>::type
get(T t1, Args... args)
{
        return 
                static_cast<type_at<Index, T, Args...>::type>
                (
                        reinterpret_cast<void*>
                        (
                                value_at<Index, T, Args...>::get(t1, args...)
                        )
                );
}


int main()
{
        int   * a     = new int(10);
        double* b     = new double(3.14);
        std::string c = "But I'm a string :(";

        std::cout<< *get<0>(a, b, &c) <<"\n";
        std::cout<< *get<1>(a, b, &c) <<"\n";
        std::cout<< *get<2>(a, b, &c) <<"\n";
}

that doesn't work on GCC 4.8.1 but compiles and runs fine in VS2012 with the Nov CTP compiler ( didn't try clang by the way )

Which compiler is right?

full example

Mohit Kanwar
  • 2,962
  • 7
  • 39
  • 59
user1233963
  • 1,450
  • 15
  • 41
  • 4
    clang++ correctly complains about a missing `typename` here: `static_cast::type>`. g++ also complains about that, but the error message is much less helpful. – dyp Aug 12 '13 at 19:19
  • Seems like after adding that typename it works in GCC too... well this is embarrassing :) – user1233963 Aug 12 '13 at 19:22
  • 1
    Would be useful to provide at least the error message and your idea why it is/is not right. – PlasmaHH Aug 12 '13 at 19:22
  • 2
    See [Where and why do I have to put the “template” and “typename” keywords?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – dyp Aug 12 '13 at 19:22
  • Note that you can cast any object pointer to "pointer to *cv* `void`" using an implicit cast (no `reinterpret_cast` is required). – dyp Aug 12 '13 at 19:24
  • @DyP thanks for that, made the code a little bit more readable – user1233963 Aug 12 '13 at 19:25
  • Why do you need that `static_cast` anyway? – dyp Aug 12 '13 at 19:26
  • I don't like implicit conversions – user1233963 Aug 12 '13 at 19:27
  • 1
    As far as I understand your code, the return type of the global `get` and the `value_at::get` specialization used there are identical. No conversion should be required. [Live example](http://coliru.stacked-crooked.com/view?id=b890639a345f76ee42fb1723d8373cf7-7885f3d27d18134d8479d2ab5250c852) – dyp Aug 12 '13 at 19:28
  • You're right again. No idea why I had the impression that I had to cast it. Guess I got lost in the templates – user1233963 Aug 12 '13 at 19:31

1 Answers1

1

In this particular case GCC is more standard compliant as you are missing typename when referring to a dependent type in type_at<Index, T, Args...>::type part of your code.

Clang is also doing a similar thing and gives a nice error message (as always):

./test.cc:40:29: error: missing 'typename' prior to dependent type name 'type_at<Index, T, Args...>::type'
                static_cast<type_at<Index, T, Args...>::type>
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                            typename 
1 error generated.