为什么 GCC 没有给我一个错误
Why isn't GCC giving me an error
GCC并没有给我一个我希望它会出现的例子的错误:
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;
};
当不使用复制构造函数时不会发生此错误(也就是说,当使用了复制构造函数时会发生此错误)。
由于模板的原因,我不能简单地将副本ctor移动到代码文件中,并在编译时失败。
我怎么能让它失败呢?
这不是SFINAE,它不应该能够实例化模板。如果复制ctor本身就是一个模板方法(比如说放入:
template<class U=T>
在上面的线路上,那么它将是SFINAE。
我使用的是GCC 4.8.1,当然是-pedantic -Wall -Wextra
和-std=c++11
我希望通过来失败
int main() {
FirstVector<CannotBeCopied> whatever;
}
我知道GCC只是懒惰,没有做它不需要做的工作,但我不喜欢如果我在代码文件中显式实例化这个模板,我会得到一个错误。有没有办法得到我想要的错误?
如果您实际上没有创建模板的实例,则不需要调用复制构造函数-如果您不使用它,甚至不会为CannotBeCopied
创建模板代码。调用复制构造函数,您将得到错误:
FirstVector<CannotBeCopied> a;
FirstVector<CannotBeCopied> b = a;
编辑:您还可以通过添加来使用模板的所有成员的显式实例化
template class FirstVector<CannotBeCopied>;
(语言规范§14.7.2)
C++中的模板只有在使用时才被物化。其他的都太贵了。
正如你可能听说的,C++模板正在变得完整,所以评估它们可能非常昂贵。IIRC在某个地方有一个Fibonnaci<17> ,它会让编译器计算这个数字。。。
特别是,这意味着死代码将被消除,并且只有当您尝试使用复制构造函数时,c++编译器才会失败。
这不仅仅是GCC懒惰的问题;按照标准,它肯定被禁止做你想让它做的事。[温度指示]/p1,2,11:
1除非类模板专门化已经明确实例化(14.7.2)或显式专用(14.7.3),类当在需要完全定义的对象类型,或者当类的完整性类型会影响程序的语义。[…]的隐式实例化类模板专门化导致声明,但不是定义、默认参数的声明,或类成员函数的异常规范〔…〕
2除非类模板或成员模板的成员显式实例化或显式专门化,专门化当专用化为在需要成员定义存在的上下文中引用。[…]
11实现不应隐式实例化函数模板、变量模板、成员模板、非虚拟成员函数、成员类或类模板的静态数据成员这不需要实例化。
这允许您拥有例如仅移动类型的std::vector
。它们的副本构造函数不会编译,但只要不使用它们,std::vector<std::unique_ptr<T>>
就完全有效。
为了迫使它失败,您可以在FirstVector
:中使用static_assert
static_assert(std::is_copy_constructible<T>::value, "T must be copy constructible");
但是,请注意,这只是检查复制构造函数的声明是否可访问且未删除,而不是检查复制构造函数主体是否会编译,这意味着它将错误地报告std::vector<std::unique_ptr<T>>
是可复制构造的。
- 试图修复一个错误,该错误不会让我开始编程其余部分
- MSVC 无法根据模板参数进行数学运算,这是一个错误吗?
- 我正在尝试一个傻瓜 C++ 练习,我遇到了一个错误,说类 'GraduateStudent' 没有任何名为 'advisor' 的字段
- 零四元数和任何向量都不为零的特征积,这是一个错误吗?
- 处理程序的模块列表中有一个错误的模块"WebSocketModule"
- 在 C++ 中使用 "transform" 会给出一个错误,指出这未在作用域中声明
- 在Cython中使用C库时,我遇到了一个错误
- 我需要帮助创建一个评分系统,但它一直给我一个错误,注释掉的整数是给我带来麻烦的部分
- 我试图用c++编写递归fibonacci序列,但当我编译时,我遇到了一个错误
- 从system()调用G++会返回一个错误
- 在Visual Studio中,与std::async一起使用时不调用"thread_local"变量"析构函数,这是一个错误吗?
- 我收到一个错误无效的操作数,类型为 const char [42] 和二进制"运算符+"的双倍数
- 使用声明:GCC 和 Clang 的另一个错误?
- 全球免费给出一个错误.调试器不解释
- 相对于继承的构造函数,gcc 编译器是否还有一个错误?
- 为什么直接传递"this"指针来存档是一个错误,而另一个相同类型的指针是可以的?
- 为什么第三板有一个错误
- 如何编写一个错误结构,该结构可以包含不同的强键枚举作为错误代码
- 使用本地类型声明的G lambda被使用但从未定义 - 确实是一个错误
- 我需要在 Android Studio 中构建 NDK. 但它返回一个错误