Visual C ++ decltype не может вывести тип

Действительно ли decltype действительно глючит в Visual Studio 2012 или это действительно сложно использовать?

Пример:

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 компилируется, потому что я обернул код в decltype этой бессмысленной функцией.

ExampleFxn2 нет, VS2012 выдает чрезвычайно полезное сообщение об ошибке:

ошибка C3555: неверный аргумент для ‘decltype’

Кто-нибудь знает, что вызывает это? Кажется, мне постоянно приходится бороться с decltype, чтобы заставить его работать как положено …

Спасибо

4

Решение

Тип &ptl::static_constructor<ptl::Test, float> может быть выведено decltype(), Это похоже на ошибку в MSVC ++. И clang, и gcc согласны, что код в порядке (при условии #include <new> добавлен).

3

Другие решения

Я согласен с Dietmar: это ошибка в компиляторе. Проблема в том, что decltype не может быть применено к выражению, которое принимает адрес специализации шаблона функции. То есть следующее является минимальным воспроизведением для этой проблемы:

template <typename>
void f();

typedef decltype(&f<void>) t;

В качестве обходного пути рассмотрите возможность применения decltype непосредственно к специализации шаблона функции, затем добавив * сформировать требуемый тип указателя:

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

Пожалуйста, подумайте об открытии ошибки для этого на Microsoft Connect и размещение ссылки в качестве комментария здесь для будущих читателей (или, если вы предпочитаете не делать этого, дайте мне знать, и я был бы рад сообщить об ошибке для этой проблемы).

3

По вопросам рекламы [email protected]