Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不是';不要给我一个错误_C++_Gcc - Fatal编程技术网

C++ 为什么不是';不要给我一个错误

C++ 为什么不是';不要给我一个错误,c++,gcc,C++,Gcc,GCC没有给我一个错误,我希望它能: class CannotBeCopied { public: CannotBeCopied(const CannotBeCopied&) = delete; CannotBeCopied& operator=(const CannotBeCopied&) =delete; CannotBeCopied() { } ~CannotBeCopied() { } }; template<class T

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;
};

我知道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");