嵌套模板类型的偏特在VC 2012编译器生成“内部错误”(Partial specializatio

2019-10-23 09:11发布

在以下示例中,我有一个对象类,其限定了参考类。 双方接受的可变性作为模板参数。 在这OBJ'的情况下是“常量”,我希望禁止类型的引用“Non_Const”。 此例产生模糊的消息时,在Visual C“已编译器中发生内部错误,” ++ 2012。如果这种编译? 如果没有,为什么,是有另一种方式来完成同样的事情?

enum Mutability {Const, Non_Const};

template <typename T, Mutability U>
class Obj
{
public:
    template <Mutability V>
    class Ref
    {
    public:
        Ref() {}

        friend class Obj;
    };

    Obj() {}
};

template <typename T>
class Obj<T, Const>::template Ref<Non_Const>
{
private:
    Ref() {}
}; //error C1001: An internal error has occurred in the compiler

int main()
{
    Obj<int, Const>::Ref<Non_Const> test;
}

Answer 1:

如果你正在寻找这样做是不允许的实例V作为Ref ,当UMutability::const ,我们可以使用一些模板弄虚作假执行这一概念:

(有人比我聪明也许可以让这个简单)

enum class Mutability {Const, Non_Const};

template<Mutability T>
struct ConstMutability: std::true_type{};

template<>
struct ConstMutability<Mutability::Non_Const>: std::false_type{};

我到目前为止已经做的是地图Mutability::Conststd::true_typeMutability::Non_Conststd::false_type

现在我可以用结合std::enable_if来强制执行以下是有效的组合:

  • UConstVConst
  • U Non_ConstVConst
  • UNon_ConstVNon_Const

全码:

template <typename T, Mutability U>
class Obj
{
public:
    template <Mutability V, typename std::enable_if<
    std::is_same<ConstMutability<U>, ConstMutability<V>>::value || 
    (ConstMutability<V>::value && !ConstMutability<U>::value)
    >::type* = nullptr>
    class Ref
    {
    public:
        Ref() {std::cout << "Successfully created a Ref object" << std::endl;}

        friend class Obj;
    };

    Obj() {}
};

你可以测试正是如此:

int main()
{
    Obj<int, Mutability::Const>::Ref<Mutability::Const> test1; //pass
    //Obj<int, Mutability::Const>::Ref<Mutability::Non_Const> test2; // fail
    Obj<int, Mutability::Non_Const>::Ref<Mutability::Const> test3; // pass
    Obj<int, Mutability::Non_Const>::Ref<Mutability::Non_Const> test4; // pass
}

现场演示



Answer 2:

什么你想要做的是部分明确专门的成员类模板。 这是不合法的C ++,相同的想法基本上是试图以部分专门委员。 这是不幸的VC崩溃试图编译这个,和gcc并没有真正给予帮助的错误,但铛发生:

main.cpp:21:31: error: cannot specialize a dependent template
class Obj<T, Const>::template Ref<Non_Const>
                              ^

但是,可以明确地专注整个一路下滑:

template <>
template <>
class Obj<int, Const>::Ref<Non_Const>
{
private:
    Ref() {}
};

然后你唯一的编译错误是, Ref()private



文章来源: Partial specialization of nested template types produces “internal error” in VC++ 2012 compiler