在下面的示例中,我有一个对象类,它定义了一个引用类。两者都接受可变作为模板参数。在'obj‘是'Const’的情况下,我想不允许类型'Non_Const‘的引用。此示例生成VisualC++ 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;
}发布于 2015-06-15 19:19:54
如果您想要做的是在V是Mutability::const时不允许将U实例化为Mutability::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::Const映射到std::true_type,将Mutability::Non_Const映射到std::false_type
现在,我可以结合std::enable_if来强制执行以下有效的组合:
U是Const,V是ConstU Non_Const,V是ConstU是Non_Const,V是Non_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
}现场演示
发布于 2015-06-15 18:53:22
您要做的是部分地显式地专门化一个成员类模板。这就是无效的C++,与尝试部分专门化一个成员的想法是一样的。不幸的是,VC试图编译它时崩溃了,gcc并没有给出一个有用的错误,但是clang碰巧:
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。
https://stackoverflow.com/questions/30852246
复制相似问题