decltype and the scope operator in C++

耗尽温柔 提交于 2019-11-28 00:44:39

This transparently replaces the decltype keyword with the template based workaround. Once you no longer need to support MSVC2010 you can remove the macro definition without changing any user code:

#if _MSC_VER == 1600
#include <utility>
#define decltype(...) \
  std::identity<decltype(__VA_ARGS__)>::type
#endif

Which allows this to compile and work on MSVC10:

std::vector<int> v;
decltype(v)::value_type i = 0;

Note that std::identity isn't part of the C++ standard, but it's safe to rely on it here as the workaround is limited to a compiler which includes std::identity in its standard library implementation.

The workaround looks relatively fine but it’s not extensible and the names are horrible1. Why not use id?

template <typename T>
struct id {
    typedef T type;
};

And then:

id<decltype(FooInt)>::type::TUnderlying;

Untested, but should work.


1 As in, too verbose and even though they describe that it’s a workaround, this may be redundant and not a useful information in most of the situations.

As an alternative, you can easily pull the type out using a function template helper:

template <typename T> struct Foo
{
    typedef T TUnderlying;
};

static Foo<int> FooInt;

template <typename T>
typename Foo<T>::TUnderlying foo_underlying(Foo<T> const &)
{
    return typename Foo<T>::TUnderlying();
}

class Bar
{
public:
//    auto Automatic() -> decltype(FooInt)::Underlying
//    {
//        return decltype(FooInt)::Underlying;
//    }
    auto Automatic() -> decltype(foo_underlying(FooInt))
    {
        return foo_underlying(FooInt);
    }
};

int main()
{
    Bar bar;
    auto v = bar.Automatic();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!