下面的代码使用GCC和Clang的,但不能用Visual C++:如何在Visual C++中延迟静态数据成员的实例化?
#include <type_traits>
struct MyType {
static constexpr std::size_t it = 10;
};
struct MyType2 {
};
template<typename T>
struct Type2 {
static constexpr std::size_t it = T::it;
};
int main() {
Type2<MyType> t1;
Type2<MyType2> t2; // Visual C++ complains that MyType2::it doesn't exist
(void) t1;
(void) t2;
}
根据标准的第14.7.1:
...初始化(和任何相关方效果 - )静态 数据成员的不发生,除非静态数据成员本身是在需要的静态数据成员 的定义的方式用于存在
所以看起来这是Visual C++中的一个bug;它应该接受这个代码。
不管怎样,我还是希望能够做到这一点使用Visual C++。在不改变访问成员变量的语法的情况下,允许Visual C++工作的最简单方法是什么?我还要求当T::it
不存在Type2<T>::it
不存在,或者说,它是否则可能SFINAE断Type2<T>::it
的脑干的。
这改变了语法,所以我不希望它:
template<typename T>
struct Type2 {
template<typename = void>
static constexpr std::size_t it = T::it;
};
// Type2<MyType>::it<>
这是一个大量的工作,因为我的类将包含比简单的可变constexpr
更多:
template<typename T, typename = void>
struct Type2 {
};
template<typename T>
struct Type2<T, decltype((void) T::it)> {
static constexpr std::size_t it = T::it;
};
这似乎工作:http://coliru.stacked-crooked.com/a/1fd7999053358d43 –
你过分解读的标准。它并不是说如果从不使用成员,则允许无效的初始化器。例如。 'it =(abort(),0)'与你的例子有很大的不同,因为它会产生运行时错误而不是编译时错误。 –