为什么GCC没有给我一个错误 [英] Why isn't GCC giving me an error

查看:82
本文介绍了为什么GCC没有给我一个错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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::vectors 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆