Froglegs
Froglegs

Reputation: 1145

C++ decltype fails to deduce type

Is decltype really buggy in Visual Studio 2012 or is it actually supposed to be this hard to use?

Example:

namespace ptl
{

    struct Test
    {
        Test(float ){}
    };

    template<class T, class A0>
    static T* static_constructor(void* p, A0 a0){return new(p) T(a0);}

    template<class T>
    T*  MakeVS2012Happy(T*);
}

inline auto ExampleFxn() -> decltype(ptl::MakeVS2012Happy(&ptl::static_constructor<ptl::Test, float>)) 
{
   return &ptl::static_constructor<ptl::Test, float>;
}
inline auto ExampleFxn2() -> decltype(&ptl::static_constructor<ptl::Test, float>)
{
   return &ptl::static_constructor<ptl::Test, float>;
}

ExampleFxn compiles because I've wrapped the code in the decltype with that pointless function.

ExampleFxn2 does not, VS2012 spits out the extremely helpful error message:

error C3555: incorrect argument to 'decltype'

Anyone know what causes this? I seem to constantly have to fight against decltype to get it to work as expected...

Thanks

Upvotes: 4

Views: 1531

Answers (2)

James McNellis
James McNellis

Reputation: 354979

I agree with Dietmar: This is a bug in the compiler. The issue appears to be that decltype cannot be applied to an expression that takes the address of a function template specialization. That is, the following is a minimal repro for this issue:

template <typename>
void f();

typedef decltype(&f<void>) t;

As a workaround, consider applying decltype to the function template specialization directly, then adding * to form the required pointer type:

inline auto ExampleFxn2()
    -> decltype(ptl::static_constructor<ptl::Test, float>)*
{
   return &ptl::static_constructor<ptl::Test, float>;
}

Please consider opening a bug for this on Microsoft Connect and posting a link as a comment here for future readers (or, if you would prefer not to, let me know and I would be happy to open a bug for this issue).

Upvotes: 3

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153792

The type of &ptl::static_constructor<ptl::Test, float> can be deduced by decltype(). This looks like a bug in MSVC++. Both clang and gcc agree that the code is fine (assuming #include <new> is added).

Upvotes: 3

Related Questions