C++ 为什么不是';不要给我一个错误
GCC没有给我一个错误,我希望它能:C++ 为什么不是';不要给我一个错误,c++,gcc,C++,Gcc,GCC没有给我一个错误,我希望它能: class CannotBeCopied { public: CannotBeCopied(const CannotBeCopied&) = delete; CannotBeCopied& operator=(const CannotBeCopied&) =delete; CannotBeCopied() { } ~CannotBeCopied() { } }; template<class T
class CannotBeCopied {
public:
CannotBeCopied(const CannotBeCopied&) = delete;
CannotBeCopied& operator=(const CannotBeCopied&) =delete;
CannotBeCopied() { }
~CannotBeCopied() { }
};
template<class T>
class FirstVector {
public:
FirstVector() {
size = 1;
data = new T[size];
}
~FirstVector() {
delete[] data;
}
FirstVector(const FirstVector& source) {
size = source.size;
data = new T[size];
for(int k=0;k!=size;k++) {
data[k] = source.data[k]; //<--I EXPECT AN ERROR HERE
}
}
private:
int size;
T* data;
};
我知道GCC只是懒惰,不做它不需要做的工作,但我不喜欢这样,如果我在代码文件中显式地实例化这个模板,我会得到一个错误。有没有办法得到我想要的错误?如果您没有实际创建模板的实例,则不需要调用复制构造函数-如果您不使用它,甚至不会为
创建模板代码。调用复制构造函数,您将得到以下错误:
FirstVector<CannotBeCopied> a;
FirstVector<CannotBeCopied> b = a;
FirstVector a;
第一向量b=a;
编辑:您还可以通过添加
template class FirstVector<CannotBeCopied>;
模板类FirstVector;
<>(P< 7.7.2语言规范) < P>模板在使用时<>强>当使用< /强>时。
其他一切都太贵了
正如你可能听说的,C++模板是图灵完成的,所以评估它们可能是非常昂贵的。IIRC有一个Fibonnaci的例子,它会让编译器计算这个数字
特别是这意味着死代码将被消除,C++编译器只会在使用复制构造函数时失败。
< P>这不仅仅是GCC懒惰的问题;标准明确禁止它做你想让它做的事。[临时安装]/p1、2、11:
1,除非已明确指定类模板专用化
实例化(14.7.2)或显式专门化(14.7.3),类
当
专门化是在需要
完全定义的对象类型或类的完整性
类型影响程序的语义。[…]的隐式实例化
类模板专门化会导致
声明,但不包括定义、默认参数或
类成员函数的异常规范[…]
2除非类模板或成员模板的成员已
显式实例化或显式专门化,专门化
当指定专门化时,隐式实例化成员的
在要求成员定义存在的上下文中引用。
[……]
11实现不应隐式实例化函数
模板、变量模板、成员模板、非虚拟成员
函数、成员类或类模板的静态数据成员
这不需要实例化
例如,这允许您拥有仅移动类型的std::vector
s。它们的复制构造函数不会编译,但只要不使用它们,std::vector
就完全有效
要强制它失败,可以在FirstVector
中使用static\u assert
:
static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");
static_assert(std::is_copy_constructible::value,“T必须是可复制的”);
但是,请注意,这只检查复制构造函数的声明是否可访问且未被删除,而不是复制构造函数的主体是否将编译,这意味着它会错误地报告std::vector
是可复制构造函数。您是否尝试调用FirstVector
的复制构造函数?哦,是@immibis-如果您实际使用它,它会给出错误。当它被实例化为没有复制赋值的类型时,它应该给出错误。Java语言规范调用Java指针,指针。让他们看看。@Cheersandhth.-阿尔夫,我以为我会因为愤怒而一度昏厥。有些人走得太远了:p第一行应该足以导致错误。如果显式实例化模板,则会出现错误(就像将其放入代码文件中一样),请记住“FirstVector a;”方法创建无法完成的类型FirstVector
。@I'mgetthere:不,这可以完成。它根本无法复制。我现在不能删除它并重新发布,但这并不能回答问题,停止投票!编译器不需要隐式实例化不使用的成员。类的显式实例化强制实例化所有成员。这都是正确的行为。谢谢!很高兴有一个能回答问题并正确回答的答案!非常感谢你。
template class FirstVector<CannotBeCopied>;
static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");