构造函数内指向模板成员函数的指针是否会强制实例化?
考虑以下头文件:
// Foo.h
class Foo {
public: template <typename T> void read(T& value);
};
似乎在类的构造函数中分配一个指向 Foo::read
的指针,然后声明该变量,会导致实例化:
// 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
请参阅 这个问题。
Consider the following header file:
// Foo.h
class Foo {
public: template <typename T> void read(T& value);
};
It seems that assigning a pointer to Foo::read<T>
in the constructor of a class, of which variable is then declared, cause instantiation:
// 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;
Is this solution reliable / portable / standard-conformant? (It works at least with Intel and GNU compilers.)
If you wonder why not to simply use template Foo::read<int>(int&);
see this question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,您的解决方案是便携式的。这是一种不同的方式
现在,每当
Bar
被隐式实例化时,它都会隐式实例化Foo::read
。不需要创建任何对象。Yes, your solution is portable. Here is a different way
Now whenever
Bar<T>
is implicitly instantiated, it will implicitly instanitateFoo::read<T>
. No object needs to be created.14.7.1 是它所在的位置。 /2 说:
就像调用函数一样,获取成员函数指针需要在程序中(可能在另一个 TU 中)定义该函数。我相信这就是“需要函数定义存在”的意思,所以这就是导致实例化的原因。
还有/9:
因此,GCC 和 Intel 实例化它的事实表明其他人都应该这样做,因为不需要的东西就是被禁止的。当然,假设每个人都遵守。
14.7.1 is where it's at. /2 says:
Just like calling a function, taking a member function pointer requires that the function is defined in the program (perhaps in another TU). I believe that's what "requires a function definition to exist" means, so this is what causes the instantiation.
There's also /9:
So the fact that GCC and Intel instantiate it suggests that everyone else should, since that which is not required is forbidden. Assuming everyone conforms, of course.
当
Bar
的对象使用实际类型声明时,肯定是的;它将实例化Foo::read()
。但是,它将仅限于该函数(例如Foo::write()
将不会被实例化)。换句话说,如果您尝试这样的操作:
那么在您声明
X
之前,Foo::read()
将不会被实例化。编辑:
在上面的例子中,直接声明
Bar
(X
内的 b1;int
而不是T
)也是不够的。其包含类型X<>
必须使用实际(即非模板)类型进行实例化。When objects for
Bar<type>
are declared with actual types then definitely, Yes; it will instantiateFoo::read<type>()
. However, it will be limited only to that function (sayFoo::write<type>()
will not be instantiated).In other way, if you try something like this:
Then
Foo::read<int>()
will not be instantiated until you declareX<int>
.Edit:
In above example, directly declaring
Bar<int> b1;
(int
instead ofT
) insideX
is also NOT sufficient. Its containing typeX<>
has to be instantiated with actual (i.e. non-template) type.