如何在 Visual C++ 中延迟静态数据成员的实例化?
How do I delay the instantiation of a static data member in Visual C++?
以下代码适用于 GCC 和 Clang,但不适用于 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 节:
... the initialization (and any associated side-effects) of a static
data member does not occur unless the static data member is itself
used in a way that requires the definition of the static data member
to exist
看来这是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<>
这是很多工作,因为我的 class 将包含多个简单的 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;
};
您可以继承 it
(当它存在时)而不是直接声明它:
template<typename T, typename = void>
struct ItHolder
{};
template<typename T>
struct ItHolder<T, decltype((void) T::it)> {
static constexpr std::size_t it = T::it;
};
template<typename T>
struct Type2 : ItHolder<T> {
};
换句话说,只需采用您已经建议的内容并使用另一层间接将其组合起来。
以下代码适用于 GCC 和 Clang,但不适用于 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 节:
... the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist
看来这是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<>
这是很多工作,因为我的 class 将包含多个简单的 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;
};
您可以继承 it
(当它存在时)而不是直接声明它:
template<typename T, typename = void>
struct ItHolder
{};
template<typename T>
struct ItHolder<T, decltype((void) T::it)> {
static constexpr std::size_t it = T::it;
};
template<typename T>
struct Type2 : ItHolder<T> {
};
换句话说,只需采用您已经建议的内容并使用另一层间接将其组合起来。