为什么GCC没有给我一个错误 [英] Why isn't GCC giving me an error
问题描述
GCC并未在我希望的示例中给我一个错误:
GCC isn't giving me an error on an example I've made where I was hoping it would:
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;
};
当不使用复制构造函数时(即使用复制构造函数时,不会发生此错误).
This error doesn't happen when the copy constructor isn't use (that is, it does happen when the copy constructor is used).
由于模板的原因,我不能简单地将copy-ctor移到代码文件中,并且在编译时会失败.
Because of the template I cannot simply move the copy-ctor into a code file and have that fail when it compiles.
如何使它失败?
这不是SFINAE,它应该无法实例化模板.如果copy-ctor本身是模板方法(例如,输入:
This is not SFINAE, it should not be able to instantiate the template. If the copy-ctor was itself a template method (say by putting:
template<class U=T>
在上面的一行中,那就是SFINAE.
on the line above, then it'd be SFINAE.
我正在使用GCC 4.8.1,-pedantic -Wall -Wextra
和-std=c++11
I am using GCC 4.8.1, -pedantic -Wall -Wextra
of course, and -std=c++11
我希望通过以下操作使它失败:
I was hoping to get this to fail with:
int main() {
FirstVector<CannotBeCopied> whatever;
}
我知道GCC只是懒惰而不必做它不需要做的工作,但是我不喜欢这样,如果我要在代码文件中显式实例化此模板,则会收到错误消息.有没有办法得到我想要的错误?
I know that GCC is just being lazy and not doing work it doesn't need to, but I do not like that if I were to explicitly instantiate this template in a code file, I'd get an error. Is there a way to get the error I want?
推荐答案
这不仅仅是GCC懒惰的问题;绝对禁止它按照标准执行您想要的操作. [temp.inst]/p1、2、11:
It's not just a matter of GCC being lazy; it is affirmatively prohibited from doing what you want it to do by the standard. [temp.inst]/p1, 2, 11:
1除非明确指定了类模板专业化 实例化(14.7.2)或显式专门化(14.7.3)的类 当 在需要以下条件的上下文中引用专业化 完全定义的对象类型或类的完整性 类型会影响程序的语义. [...]的隐式实例化 类模板特化导致隐式实例化 声明,但不包括定义,默认参数或 类成员函数的异常规范[...]
1 Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3), the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program. [...] The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or exception-specifications of the class member functions [...]
2除非已经有类模板的成员或成员模板 显式实例化或显式专业化 当专门化是 在需要成员定义存在的上下文中引用. [...]
2 Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist. [...]
11实现不得隐式实例化函数 模板,变量模板,成员模板,非虚拟成员 函数,成员类或类模板的静态数据成员 不需要实例化.
11 An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation.
这使您可以拥有例如std::vector
个仅移动类型.它们的副本构造函数不会编译,但是只要您不使用它们,std::vector<std::unique_ptr<T>>
就是完全有效的.
This allows you to have, e.g., std::vector
s of move-only types. Their copy constructors will not compile, but as long as you don't use them, a std::vector<std::unique_ptr<T>>
is perfectly valid.
要强制其失败,可以在FirstVector
内使用static_assert
:
To force it to fail, you might use a static_assert
inside FirstVector
:
static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");
但是,请注意,这仅检查副本构造函数的声明是否可访问且未被删除,而不检查副本构造函数的主体将进行编译,这意味着它将错误地报告std::vector<std::unique_ptr<T>>
是可复制构造的.
Note, however, that this only checks that a declaration of the copy constructor is accessible and not deleted, not that the body of the copy constructor will compile, which means that it will falsely report that std::vector<std::unique_ptr<T>>
is copy constructible.
这篇关于为什么GCC没有给我一个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!