这是来自ISO C++标准14.6.4.1实例点的声明
4.If a virtual function is implicitly instantiated, its point of instantiation
is immediately following the point of instantiation of its enclosing
class template specialization.
5.An explicit instantiation directive is an instantiation point for the
specialization or specializations specified by the explicit
instantiation directive.
6.The instantiation context of an expression that depends on the
template arguments is the set of declarations with external linkage
declared prior to the point of instantiation of the template
specialization in the same translation unit.我无法为这整个部分写一个程序。我正在试着从昨天开始写这部分的程序。
请注意,通常我会试着问一个1或更多的分数。在任何部分。但在这里,我无法理解本节中的任何一点。
所以,任何人都可以为我提供一个代码来理解这一节。
发布于 2010-09-28 15:24:52
前两个语句解释了某些模板构造的实例化点在哪里;它没有引入新的模板构造。因此,您可以重用前面的示例。
第三条语句(14.6.4.1/6)告诉我们实例点的意义:实例点是在名称查找的第二阶段中查找名称的点。在实例化之前声明的名称是可见的;在实例化之后声明的名称是不可见的。(在两阶段名称查找的第一阶段中,在模板定义之前的声明集中查找非依赖名称)。
因此,假设:
template <typename T> void foo() {
T() + T();
}表达式T()+T()的实例化上下文是在foo<T>的相应实例化点之前的一组声明。在这些上下文中查找名称operator+,并包括在此定义之后但在实例化点之前的声明。
发布于 2016-05-28 22:18:29
关于实例化上下文,似乎总是有大量的问题。
MSalters给出的例子有问题:
template <typename T> void foo() {
T() + T();
}考虑以下代码:
#include <iostream>
using namespace std;
template <typename T> void foo() {
T() + T();
}
class A {};
void operator +(const A&, const A&)
{
cout << "Called operator+(const A&, const A&)" <<endl;
}
int main()
{
foo<A>();
}它可以在所有编译器上编译和运行,但如果您将类A定义放入名称空间:
#include <iostream>
using namespace std;
template <typename T> void foo() {
T() + T();
}
namespace {
class A {};
}
void operator+(const A&, const A&)
{
cout << "operator+(const N::A&, const N::A&)" << endl;
}
int main()
{
foo<A>();
}Clang将无法编译,但VC++和gcc可以编译。为什么?哪个编译器符合该规范?
坦率地说,我不知道。有些编译器,比如gcc,在这方面甚至自相矛盾。考虑以下代码:
#include <iostream>
using namespace std;
template <typename T> void foo() {
g(T());
}
namespace {
class A {};
}
void g(A a)
{
cout << "g(A)" << endl;
}
int main()
{
foo<A>();
}简单地把"operator+“改成"g",gcc编译失败?为什么?
如果规范是正确的,那为什么GCC找不到g呢?
6.依赖于模板参数的表达式的实例化上下文是一组具有外部链接的声明
在模板实例化之前声明
同一翻译单元中的专业化。
当我阅读Bjarne Stroustrup的"The C++ Programming Language,第4版“,26.3.5模板和命名空间时,他有这个例子:
namespace N{
class A{};
char f(A);
}
char f(int);
template<typename T>
char g(T t)
{
return f(t); //choose f() depending on what T is
}
char f(double);
char c1 = g(N::A()); //causes N::f(N::A) to be called
char c2 = g(2); //causes f(int) to be called
char c3 = g(2.1); //causes f(int) to be called, f(double) not considered这里,f(t)显然是依赖的,所以我们不能在定义点绑定f。为了生成g(N::A)的专门化,编译器在名称空间N中查找称为f()和fins N::f(N::A)的函数。
找到f(int)是因为它在模板定义点的作用域中。没有找到f(双精度),因为它在模板的定义点不在作用域中,并且依赖于参数的查找没有找到只接受内置类型的参数的全局函数。
所以这真是一团糟!
https://stackoverflow.com/questions/3810281
复制相似问题