[dcl.spec.auto]/14国[强调我的]:
显式实例化声明不会导致使用占位符类型声明的实体的实例化,但也不会阻止根据需要对该实体进行实例化以确定其类型。[示例:
template <typename T> auto f(T t) { return t; }
extern template auto f(int); // does not instantiate f<int>
int (*p)(int) = f; // instantiates f<int> to determine its return type, but an explicit
// instantiation definition is still required somewhere in the program
-结束示例]
和[temp.explicat]/11声明[强调我的]:
template <class T>
struct Foo {
static const auto& foo() { static T t; return t; }
};
// explicit instantiation declarations
extern template const auto& Foo<void>::foo();
extern template const auto& Foo<int>::foo();
int main() {}
现在,考虑我们是否在类模板foo
中的friend声明中定义了friend函数:
template <class T>
struct Foo {
static const auto& foo() { static T t; return t; }
friend void bar() { }
};
void bar();
如果在同一翻译单元中实例化了foo
的多个专门化,则将违反[basic.def.odr]/1:
任何翻译单元不得包含任何变量、函数、类类型、枚举类型或模板的一个以上定义。
template <class T>
struct Foo {
static const auto& foo() { static T t; return t; }
friend void bar() { }
};
void bar();
extern template const auto& Foo<void>::foo();
extern template const auto& Foo<int>::foo();
int main() {}
铿锵
错误:重新定义条形图
注意:在实例化模板类foo
时,此处请求:extern template const auto&foo
但是我从来没有请求(或者afaict使用这些专门化的方式)将foo
或foo
专门化实例化。
因此,对于这个问题:
(1)注意,即使foo()
没有使用占位符类型声明,同样的问题(和编译器行为)也适用,但是我们将无法依赖[dcl.spec.auto]/14的明确性,但我们可能不需要。
(2)由于在friend声明中定义的friend是内联的,我们实际上可能会在不同的翻译单元中实例化不同的专门化,并且仍然尊重ODR,但这与本讨论无关。
类模板必须实例化的论点是,声明匹配可能需要知道关于类的明显需要实例化的事情。考虑简化的示例
template<class T>
struct A {void f(T) {}};
extern template void A<int>::f(int);
要知道成员函数是否存在,我们必须在类模板中实例化声明,通常我们不能在不实例化整个类的情况下这样做:参数类型可能依赖于类模板中的任何其他声明,我们可能需要考虑多个重载,甚至需要进行模板参数推导,以确定f
是指哪个f
。人们可以争辩说,只有当这些情况中的一种确实存在时,才应该进行实例化,这偏离了CWG2的领域(在那里,实例化显然是不可能的),但其思想是,原则上,为了决定这些问题,实例化是必要的,因为我们只是不尝试首先检查模板本身。
是否有人知道此显式特化是否有效: clang 主干 (12/3/2013) 给出以下错误: f:...\test.cpp:36:20: 错误: 从类 'O' 中出线定义 “Fun” 没有定义 1生成错误。 任何来自标准的支持参考来证明你的答案将不胜感激! 注意:我有点惊讶这是一个错误——我认为应该为任何以< code >开始实例化“Fun”的模板参数族选择专门化 这是一个叮当的错误还是我期望中的错
我正在从事一个C语言的项目,当我显式实例化模板类时,很难理解模板类的哪些成员被显式实例化。我编写了以下文件,然后使用Visual C 2008 Express Edition的发布配置编译该文件,然后将其放入反汇编程序。 忽略这个文件目前并不真正需要模板,这可以很好地编译。我将exe放入反汇编程序,它告诉我该测试 这导致测试
根据我的尝试和错误,答案似乎是否定的,这是一个简单的 将为班上的所有成员工作。然而,我读过的代码建议不是这样,如果能给出具体的答案,我将不胜感激。
这有什么问题: 我在这里尝试过:用不同的编译器https://godbolt.org/z/NkL44s: x86-64 gcc 9.2:编译 x86-64 gcc(主干):失败 x86-64 clang 6.0.0:编译 x86-64 clang 7.0.0及更高版本:失败 x64 msvc v19.22:编译 x64 msvc v19.23(内部测试):失败 那么,为什么最近的编译器会拒绝这一点
我有一个模板化的C++类,它也有一个模板化的成员函数。这个成员函数的模板参数以特定的方式依赖于类的模板参数(请参阅下面的代码)。我正在为其模板参数的两个不同值实例化(而不是专门化)该类。一切都在这一点上进行。但是,如果我调用模板化的成员函数,对第一个实例化对象的调用只会编译,而不会编译第二个。似乎编译器没有为模板类的第二次实例化实例化模板化成员函数。我正在使用“g++filename.cpp”编译
我有一个类模板和一个函数模板定义了一个,它引用要绑定到的模板类型。 我想要的是将< code>make_obj函数声明为< code>friend,这样它可以创建< code>Obj的,但是其他人不能(除了通过copy ctor)。 我尝试了几个朋友声明,包括 和 后者是使< code>make_obj的所有模板实例化成为< code>Obj类的朋友的不太理想的尝试。然而,在这两种情况下,我得到相