问题描述
我需要获取在实例化模板时提供的类型。考虑下面的例子:
template< typename T> struct Foo
{
typedef T TUnderlying;
};
static Foo< int> FooInt;
class Bar
{
public:
auto Automatic() - > decltype(FooInt):: TUnderlying
{
return decltype(FooInt):: TUnderlying();
}
};
int main()
{
Bar bar;
auto v = bar.Automatic();
return 0;
}
这个代码的问题是使用scope操作符和decltype。 Visual C ++ 2010抱怨像这样:
错误C2039:'TUnderlying':不是'`全局命名空间'的成员
我收集了关于维基百科主题的一些信息:
日本ISO成员机构在评论C ++ 0x的正式委员会草案时指出, 一个范围操作符(::)不能应用于decltype,但它应该是这样的情况下,从一个实例获取成员类型(嵌套类型)如下:[16]
vector< int> v;
decltype(v):: value_type i = 0; // int i = 0;
这个和类似的问题都由David Vandevoorde解决,并于2010年3月投票进入工作文件。
所以我估计Visual C ++ 2010没有这个实现。我想出了这个解决方法:
template< typename T& struct ScopeOperatorWorkaroundWrapper
{
typedef typename T :: TUnderlying TTypedeffedUnderlying;
};
auto Automatic() - > ScopeOperatorWorkaroundWrapper< decltype(FooInt)> :: TTypedeffedUnderlying
{
return ScopeOperatorWorkaroundWrapper< decltype(FooInt)> :: TTypedeffedUnderlying();
}
我错过了更优雅, >
这会以基于模板的解决方法透明地替换 decltype
关键字。一旦您不再需要支持MSVC2010,您可以删除宏定义而不更改任何用户代码:
#if _MSC_VER == 1600
/ pre>
#include< utility>
#define decltype(...)\
std :: identity< decltype(__ VA_ARGS __)> :: type
#endif
它允许在MSVC10上编译和工作:
std :: vector< int> v;
decltype(v):: value_type i = 0;
注意
std: :identity
不是C ++标准的一部分,但是在这里依赖它是安全的,因为解决方法仅限于包含std :: identity
在其标准库实现。I need to obtain the type which was supplied when instantiating a template. Consider the following example:
template <typename T> struct Foo { typedef T TUnderlying; }; static Foo<int> FooInt; class Bar { public: auto Automatic() -> decltype(FooInt)::TUnderlying { return decltype(FooInt)::TUnderlying(); } }; int main() { Bar bar; auto v = bar.Automatic(); return 0; }
Problem with this code is using the scope operator together with decltype. Visual C++ 2010 complains like this:
error C2039: 'TUnderlying' : is not a member of '`global namespace''
I gathered some information on the topic on Wikipedia:
While commenting on the formal Committee Draft for C++0x, the Japanese ISO member body noted that "a scope operator(::) cannot be applied to decltype, but it should be. It would be useful in the case to obtain member type(nested-type) from an instance as follows":[16]
vector<int> v; decltype(v)::value_type i = 0; // int i = 0;
This, and similar issues were addressed by David Vandevoorde, and voted into the working paper in March 2010.
So I reckon the Visual C++ 2010 does not have this implemented. I came up with this workaround:
template <typename T> struct ScopeOperatorWorkaroundWrapper { typedef typename T::TUnderlying TTypedeffedUnderlying; }; auto Automatic() -> ScopeOperatorWorkaroundWrapper<decltype(FooInt)>::TTypedeffedUnderlying { return ScopeOperatorWorkaroundWrapper<decltype(FooInt)>::TTypedeffedUnderlying(); }
Did I miss any solution which is more elegant and less verbose?
解决方案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 includesstd::identity
in its standard library implementation.这篇关于decltype和C ++中的作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!