最近我写了一些代码编译,导致崩溃窗口出现消息"编译器驱动程序已停止工作"。仍然重现此崩溃的最小代码如下。
namespace _private_
{
// Using SFINAE to figure out the return type of T::operator[].
// If T does not have operator[], then class T itself is used,
// so that return type of T::operator[] is calculated as
// type = esists(T::operator[]) ? typeof(T[0]) : T;
struct SquareBracesReturnType
{
private:
template<class T>
static decltype(std::declval<T>()[0]) test(T* t);
template<class T>
static T test(...);
public:
template<class T>
using type = decltype(test<T>(0));
};
}
template<class TArray>
using SquareBracesReturnType = _private_::SquareBracesReturnType::type < TArray > ;
template<class TArray, class TSubArray = SquareBracesReturnType<TArray>>
struct ArrayTypeTraits
{
using SubArrayTypeRaw = TSubArray;
using SubArrayType = typename std::remove_reference<SubArrayTypeRaw>::type;
using SubarrayTypeTraits = ArrayTypeTraits < SubArrayType, typename SquareBracesReturnType<SubArrayType> > ;
using ArrayType = TArray;
static const size_t nDim = 1 + SubarrayTypeTraits::nDim;
using ElementType = typename SubarrayTypeTraits::ElementType;
private:
template<class T, class TArg>
static TArg dummyFunc(SubArrayTypeRaw(T::*)(TArg));
public:
using IndexType = decltype(dummyFunc(&TArray::operator[]));
};
template<class T>
struct ArrayTypeTraits < T, T >
{
using ArrayType = T;
static const size_t nDim = 0u;
using ElementType = T;
};
template <class TArray>
using IndexTypeOf = typename ArrayTypeTraits<TArray>::IndexType;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ArrayTypeTraits<vector<double >>::IndexType j = 3u; // line 1
IndexTypeOf<vector<double >> i = 3u; // line 2
double d = 0.0; // line 3
//d = i; // <-----uncomment this to break compiler // line 4
return 0;
}
要观察崩溃,标记为line 4
的行应取消注释。但即使在调试时注释了这一行,很明显编译器无法确定i
的类型。监视窗口中的所有变量都是空的,表示出现了问题。评论line 2
可以解决问题。这真的很奇怪,因为第2行的i
类型与第1行的j
类型相同。第1行和第2行实际上是完全等效的。