首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套模板类型的部分专门化在VC++ 2012编译器中产生“内部错误”

嵌套模板类型的部分专门化在VC++ 2012编译器中产生“内部错误”
EN

Stack Overflow用户
提问于 2015-06-15 18:19:31
回答 2查看 373关注 0票数 1

在下面的示例中,我有一个对象类,它定义了一个引用类。两者都接受可变作为模板参数。在'obj‘是'Const’的情况下,我想不允许类型'Non_Const‘的引用。此示例生成VisualC++ 2012中的模糊消息“编译器中发生了内部错误”。这个应该编译吗?如果没有,为什么,还有其他方法来完成同样的事情吗?

代码语言:javascript
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-15 19:19:54

如果您想要做的是在VMutability::const时不允许将U实例化为Mutability::const,那么我们可以使用一些模板技巧来执行这个概念:

(比我聪明的人可能会让事情变得更简单)

代码语言:javascript
复制
enum class Mutability {Const, Non_Const};

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

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

到目前为止,我所做的是将Mutability::Const映射到std::true_type,将Mutability::Non_Const映射到std::false_type

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

  • UConstVConst
  • U Non_ConstVConst
  • UNon_ConstVNon_Const

完整法典:

代码语言:javascript
复制
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() {}
};

你可以这样测试:

代码语言:javascript
复制
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
}

现场演示

票数 0
EN

Stack Overflow用户

发布于 2015-06-15 18:53:22

您要做的是部分地显式地专门化一个成员类模板。这就是无效的C++,与尝试部分专门化一个成员的想法是一样的。不幸的是,VC试图编译它时崩溃了,gcc并没有给出一个有用的错误,但是clang碰巧:

代码语言:javascript
复制
main.cpp:21:31: error: cannot specialize a dependent template
class Obj<T, Const>::template Ref<Non_Const>
                              ^

但是,您可以显式地专门化整个下降过程:

代码语言:javascript
复制
template <>
template <>
class Obj<int, Const>::Ref<Non_Const>
{
private:
    Ref() {}
};

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30852246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档