在构造函数中指向模板成员函数的指针会强制实例化吗?
Will the pointer to a template member function inside a constructor force instantiation?
考虑以下头文件:
// Foo.h
class Foo {
public: template <typename T> void read(T& value);
};
在类的构造函数中将指针赋值给Foo::read<T>
,然后声明该变量,似乎会导致实例化:
// Foo.cc
#include "Foo.h"
template <typename T>
void Foo::read(T& value) { /* do something */ }
template <typename T> struct Bar {
Bar<T>() { void (Foo::*funPtr)(T&) = &Foo::read<T>; }
};
static Bar<int > bar1;
static Bar<long > bar2;
static Bar<float> bar3;
这个解决方案是否可靠/可移植/符合标准?(它至少可以与Intel和GNU编译器一起工作。)
如果你想知道为什么不简单地使用template Foo::read<int>(int&);
,请看这个问题
是的,您的解决方案是可移植的。这里有一个不同的方法
template <typename T, T> struct user { };
template <typename T> struct Bar {
typedef user< void (Foo::*)(T&), &Foo::read<T> > user_type;
};
现在只要Bar<T>
被隐式实例化,它将隐式实例化Foo::read<T>
。不需要创建对象。
14.7.1是它的位置。/2说:
除非是函数模板专业化已经被明确地实例化或显式地专门化,即函数模板专门化是隐含的在专门化时实例化引用的上下文是需要一个函数定义来存在。
就像调用函数一样,接受成员函数指针要求该函数在程序中定义(可能在另一个TU中)。我相信这就是"需要一个函数定义存在"的意思,所以这就是导致实例化的原因。
还有/9:
实现不能隐式地实例化一个函数模板成员模板,非虚成员函数、成员类或静态类模板的数据成员不需要实例化。
因此GCC和Intel实例化它的事实表明其他人都应该这样做,因为不需要的是被禁止的。当然,前提是每个人都遵守。
当用实际类型声明Bar<type>
的对象时,那么肯定地,Yes;它将实例化Foo::read<type>()
。然而,它将仅限于该函数(例如Foo::write<type>()
将不会被实例化)。
换句话说,如果你尝试这样做:
template<typename T>
struct X
{
Bar<T> b1; // this is required but not sufficient to instantiate Foo::read<T>()
};
那么Foo::read<int>()
将不会被实例化,直到你声明X<int>
。
编辑:在上面的例子中,直接在X
中声明Bar<int> b1;
(int
而不是T
)也是不够的。它的包含类型X<>
必须用实际的(即非模板)类型实例化。
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 为什么我不能引用指向实例化对象的函数的指针?
- 是否可以将指向未实例化的对象的指针用作C++中的变量?
- 为什么在使用指针时不采用类成员的默认值,而不是直接实例化对象时?
- 为共享指针C++单独实例化对象
- 为什么不能在实例化对基类的引用的同时实例化指向派生类的指针?
- 模板类实例化中的指针转换无效
- 实例化一个模板类,该类采用具有不同函数签名的构造函数中的函数指针
- 为什么当我在构造函数中创建线程时,实例化对象和对象的指针的行为不同
- make_pair并push_back基指针,并实例化基指针的向量
- 声明基类类型的指针,但随后通过指向子类来实例化它.这是良好的编程实践吗?
- 使用派生类实例化基类,而不在对象定义中使用指针
- (C++)用于实例化新对象并将其分配给指向相同对象类型的指针的 2D 向量的语法
- C 实例化对象,在没有指针的情况下,其他类构造函数中没有默认构造函数
- 用push_back()实例化对象时,如何将指针传递给对象的构造函数
- 如何在 C++ 中的构造函数中正确实例化指针数组
- 使用指针实例化模板类
- 为什么可以从实例化基类对象的投射指针调用非静态派生类方法
- 当我创建一个int指针并实例化一个数组时,数组在内存中发生了什么
- 如何使用智能指针实例化对象