Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates - Fatal编程技术网

C++ 成员函数实例化

C++ 成员函数实例化,c++,templates,C++,Templates,以下在GCC 4.8.1(使用--std=c++11)上编译: struct non_default_constructible{non_default_constructible()=delete;}; 模板 结构虚拟{ T new_T(){return T();} }; int main(int argc,字符**argv){ 虚拟d; 返回0; } 棘手的部分是dummy::new_t()显然格式不正确,但这并不妨碍编译器实例化dummy 这是标准规定的行为吗?相关部分/关键字是什么?类

以下在GCC 4.8.1(使用
--std=c++11
)上编译:

struct non_default_constructible{non_default_constructible()=delete;};
模板
结构虚拟{
T new_T(){return T();}
};
int main(int argc,字符**argv){
虚拟d;
返回0;
}
棘手的部分是
dummy::new_t()
显然格式不正确,但这并不妨碍编译器实例化
dummy


这是标准规定的行为吗?相关部分/关键字是什么?

类模板的成员函数仅在上下文需要时实例化,这意味着您在尝试使用
new\t()
之前不会看到任何错误。C++标准的相关部分是:

§14.7.1隐式实例化
[temp.inst]
  • 除非函数模板专门化已显式实例化或显式专门化,否则在需要函数定义存在的上下文中引用专门化时,函数模板专门化将隐式实例化。除非调用是显式专用化函数模板或显式专用化类模板的成员函数,否则在需要默认参数值的上下文中调用函数模板或类模板的成员函数时,会隐式实例化函数模板或成员函数的默认参数

  • [示例:

    模板结构Z{
    无效f();
    void g();
    };
    void h(){
    Z a;//需要实例化类Z
    Z*p;//不需要实例化类Z
    Z*q;//不需要实例化类Z
    a、 f();//需要实例化Z::f()
    p->g();//需要实例化类Z,并且
    //需要实例化Z::g()
    }
    
    本例中的任何内容都不要求隐式地定义
    class Z
    Z::g()
    、或
    Z::f()
    实例化。-结束示例]


  • 因为你从来不叫d.new_t();然后编译器不会尝试编译已删除的构造函数。如果添加d.new_t();这是否会导致编译错误?因此,在标准术语中,模板类的成员函数本身就是一个(独立的)模板函数?@Constructor@Constructor Bug就在旁观者的眼中在我看来,这种情况下的错误在于,尽管编程显然试图阻止默认构造
    T{}
    绕过了它。@Yakk是的,这是语言的一种非常不明显的行为。@Constructor“禁止使用用户声明的构造函数进行聚合(p1008r1)”
    struct non_default_constructible { non_default_constructible() = delete; };
    
    template<class T>
    struct dummy {
        T new_t() { return T(); }
    };
    
    int main(int argc, char** argv) {
        dummy<non_default_constructible> d;
        return 0;
    }
    
    template<class T> struct Z {
      void f();
      void g();
    };
    
    void h() {
      Z<int> a;     // instantiation of class Z<int> required
      Z<char>* p;   // instantiation of class Z<char> not required
      Z<double>* q; // instantiation of class Z<double> not required
      a.f();        // instantiation of Z<int>::f() required
      p->g();       // instantiation of class Z<char> required, and
                    // instantiation of Z<char>::g() required
    }