别名模板的Visual Studio 2013编译器崩溃

时间:2014-10-15 21:24:31

标签: c++ templates visual-studio-2013

最近我写了一些代码编译,导致崩溃窗口出现消息"编译器驱动程序已停止工作"。仍然重现此崩溃的最小代码如下。

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行实际上是完全等效的。

0 个答案:

没有答案