gpt4 book ai didi

c++ - 在专门化之前使用模板?

转载 作者:IT老高 更新时间:2023-10-28 22:39:25 25 4
gpt4 key购买 nike

我发现如果您使用包装模板来使用模板第一次使用它之后,您可以专门化它。简单例子:

#include <iostream>

template<typename T>
const char* templateImpl();

template<typename T>
const char* templateGetter() { return templateImpl<T>(); }

struct S{};

int main(){ std::cout << templateGetter<S>() << std::endl; return 0; }

template<>
const char* templateImpl<S>(){ return "S"; }

这适用于每个编译器 - 我并不惊讶 MSVC 编译它,因为它处理模板的方式不同,但 GCC 和 clang 也允许它。我认为标准要求在第一次使用之前进行特化,在这种情况下,这意味着在 main 之前并希望他们报告错误。

我是否遗漏了什么,此代码标准是否符合?

澄清一下,如果我更改 templateGetter<S>templateImpl<S>在 main 中,程序不会编译并出现我期望的错误消息:

main.cpp:14:29: error: specialization of 'const char* templateImpl() [with T = S]' after instantiation

最佳答案

你(不)走运了。这是格式错误的 NDR。

[temp.expl.spec]/6-7 :

6 If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required. [...]

7 The placement of explicit specialization declarations for function templates, class templates, variable templates, member functions of class templates, static data members of class templates, member classes of class templates, member enumerations of class templates, member class templates of class templates, member function templates of class templates, static data member templates of class templates, member functions of member templates of class templates, member functions of member templates of non-template classes, static data member templates of non-template classes, member function templates of member classes of class templates, etc., and the placement of partial specialization declarations of class templates, variable templates, member class templates of non-template classes, static data member templates of non-template classes, member class templates of class templates, etc., can affect whether a program is well-formed according to the relative positioning of the explicit specialization declarations and their points of instantiation in the translation unit as specified above and below. When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.

p7 在这里并不是很有用,但我忍不住引用它:)

实例化 templateGetter<S>导致 templateImpl<S> 声明的隐式实例化.您的代码没有看到错误,因为许多实现都喜欢尽可能将模板实例化推迟到翻译单元的末尾,这是一种允许的实现技术。 (我不会在这里引用标准语言,但你会发现函数模板特化在翻译单元的末尾有一个额外的实例化点。)

给予 templateGetter推导的返回类型将强制其主体的早期实例化:

template<typename T>
auto templateGetter() { return templateImpl<T>(); }

voila :

+ g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
main.cpp:14:29: error: specialization of 'const char* templateImpl() [with T = S]' after instantiation
const char* templateImpl<S>(){ return "S"; }
^
+ clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp
main.cpp:14:13: error: explicit specialization of 'templateImpl<S>' after instantiation
const char* templateImpl<S>(){ return "S"; }
^
main.cpp:7:32: note: implicit instantiation first required here
auto templateGetter() { return templateImpl<T>(); }
^
1 error generated.

关于c++ - 在专门化之前使用模板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36997351/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com