C++-模板类实例化的问题

发布于 2017-01-06 00:33:52 字数 701 浏览 1202 评论 3

//头文件A.h
extern double f(double);
template<class T>
class AA {
public:
void changeValue() {
m_t = f(_val);
}

void TestSecret() {
f(m_t);
}

private:
int _val;
T m_t;
};
//f的定义文件,重载
#include <stdio.h>

double f(double d) {
printf("this is f(double)n");
return d;
}

int f(int f) {
printf("this is f(int)n");
return f;
}
//main.cpp

#include "A.h"

extern int f(int);
int main()
{

AA<int> a;
a.changeValue();
a.TestSecret();
return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虐人心 2017-08-26 18:49:54

这可能是因为GCC的特殊要求,使用某个函数时,GCC要求必须有这个函数的声明。例子中你声明了f(double),就是说GCC就认为你使用这个函数实例化类操作。

如果A.h中去掉了f(double)的声明,GCC会报告错误。-fpermissive选项可以取消掉这个错误,在A.h中没有f(double)声明时,仍然编译通过,此时运行结果和VS一样。

C++标准怎么规定还是要去查一下。

清晨说ぺ晚安 2017-06-15 08:51:13

这个涉及到Template 中名称决议方式,Scope of the template declaration和scope of the template instantiation的区别。
第一种情况(scope of the template declaration):

extern double foo(double);
template<class type>
class ScopRules
{
public:
void invariant() {
_member = foo(_val);
}

type type_dependent() {
return foo(_member);
}
private:
int _val;
type _member;
};

第二种情况(scope of the template instantiation):

 extern int foo(int);
ScopeRules<int> sr0;

如果有一个函数调用操作:
sr0.invariant();
那么在invariant()中调用的是哪一个foo()?

在调用操作那一点上程序中的两个函数实体是:
extern double foo(double);
extern int foo(int);

而_val的类型是int。或许你会以为调用的是int版本,但是实际上调用的是:
extern double foo(double);

template之中,对一个nonmember name决议结果是根据这个name的使用是否与“用以具现出该template的参数类型“有关而决定的。如果其使用互不相关,那么就以scope of the template declaration来决定name,如果其使用互有关联,那么就以scope of the template instantiation来决定name。

如果是sr0.type_dependent();
此时调用的foo()必须在scope of the template instantiation中决议。本例中这个scope有两个foo()函数的声明,由于_member的类型在本例为int,因此应该调用int版的foo(),如果ScopeRules是以double具现出来的,那就调用double版的foo()。

(祥见inside the c++ object model 7.1)

泛泛之交 2017-01-15 22:07:22

我用 VS2010 的输出结果是:

用一个在线编译器“codepad”的输出结果也是一样的:

 this is f(int)
this is f(int)

不是你的结果,这就很好理解了

 void changeValue() {
m_t = f(_val);
}

这个函数 _val 是int 类型,肯定是调 int 的那个f。

  void TestSecret() {
f(m_t);
}

这个函数,m_t 的类型是 T,而你的类模板就是实例化为 int 类型,所以它就是 int 类型,也是调int的那个 f。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文