我应该声明我的功能模板专长还是定义足够? [英] Should I declare my function template specializations or is defining them enough?

查看:123
本文介绍了我应该声明我的功能模板专长还是定义足够?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些可以检查的课程.实现此功能的代码在头文件中声明一个功能模板,并在不同的源文件中对其进行专门处理:

I have some classes which can be checked. The code which implements this declares a function template in a header file and specializes it in different source files:

// check.h
template <class T>
bool check(const T& object);

// class1.h
struct Class1 {int mass;};

// check_class1.cpp
#include "class1.h"
#include "check.h"
template <>
bool check(const Class1& object) {return object.mass < 100;}

// class2.h
struct Class2 {int price;};

// check_class2.cpp
#include "class2.h"
#include "check.h"
template <>
bool check(const Class2& object) {return object.price < 1000;}

// class3.h
struct Class3 {int x;};

... // 10 more classes which I can check

此代码的用法如下:

#include "class1.h"
#include "class2.h"
#include "class3.h"
#include "check.h"

int main()
{
    Class1 object1{50};
    Class2 object2{500};
    Class3 object3{8};
    check(object1); // OK
    check(object2); // OK
    check(object3); // a link error appears here
}

这很好.当我添加另一个可以检查的类Class3时,我不需要触摸头文件,因为它定义了非常宽的接口.如果我忘记为Class3实现check功能,则链接器将通过错误消息提醒我.

This works pretty well. When I add another class Class3 which I can check, I don't need to touch the header file, because it defines a very wide interface. If I forgot to implement the check function for Class3, the linker will remind me with an error message.

我的问题是:这种行为是否得到保证,还是我的代码靠运气工作?我正在使用Visual Studio.

My question is: is this behavior guaranteed, or does my code work by luck? I am using Visual Studio.

如果我想对函数模板进行专业化处理,是否不应该在头文件中声明我所有的专业化处理?

If I want to specialize my function template, shouldn't I declare all my specializations in the header file?

推荐答案

我将这些声明放在安全的一面(好吧,假设出于某种原因我不重载).我认为法律对此并不十分明确.首先,我们有

I'd add those declarations to be on the safe side (well, assuming I don't overload instead for whatever reason). I don't think the law is too clear on that. For one, we have

[temp.expl.spec]

6 如果是模板,则是成员模板或班级成员 模板是明确专门的,则专门化应为 在第一次使用该专业化之前声明 在每个翻译单元中进行隐式实例化 发生了这样的用途;无需诊断.如果程序 没有提供明确专业化的定义,并且 要么以一种会导致 进行隐式实例化或成员是虚拟成员 功能,程序格式错误,无需诊断.一个 隐式实例化永远不会为显式生成 已声明但未定义的专业化.

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. If the program does not provide a definition for an explicit specialization and either the specialization is used in a way that would cause an implicit instantiation to take place or the member is a virtual member function, the program is ill-formed, no diagnostic required. An implicit instantiation is never generated for an explicit specialization that is declared but not defined.

如果我没看错的话,这意味着如果将显式专业化添加到main.cpp,则它必须出现在之前 main.因为那是可能发生隐式实例化的地方.本段不会使您的代码完全脱离格式不正确的NDR,因为用法和显式专门化会出现在不同的TU中.但这确实引起了人们的关注.

Which, if I read correctly, means that if an explicit specialization is added to main.cpp, then it must appear before main. Because that is where an implicit instantiation may occur. The paragraph doesn't make your code flat out ill-formed NDR, because the usage and the explicit specialization appear in different TU. But it does raise concerns.

另一方面,有一段:

[温度]

7 函数模板,类模板的成员函数, 变量模板或类模板的静态数据成员应为 在每个隐含的翻译单元中定义 实例化,除非显式地指定了相应的专业化 在某些翻译单元中实例化;无需诊断.

7 A function template, member function of a class template, variable template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated unless the corresponding specialization is explicitly instantiated in some translation unit; no diagnostic is required.

这一点使我们可以在单独的未看到的TU中明确地实例化.但这并没有为显式专业提供余地.我不能说这是故意还是遗漏.

This one allows us to explicitly instantiate in separate unseen TU's. But it doesn't provide an allowance for explicit specializations. Whether or not that's intentional or an omission I cannot say.

它起作用的原因很可能是由于整个过程的实现方式.当函数声明被隐式实例化时,它会产生一个符号,恰好与显式专业化所产生的符号匹配.匹配的符号意味着一个快乐的链接器,因此所有内容都可以构建并运行.

The reason it works is likely due to how the whole thing is implemented. When the function declaration is implicitly instantiated it produces a symbol that just so happens to match the one produced by the explicit specialization. Matching symbols means a happy linker, so everything builds and runs.

但是从语言律师的角度来看,我认为我们可以将行为定义为无遗漏.它之所以未定义,仅仅是因为该标准未解决该问题.因此,回到我的开场白,我将它们添加到安全的一面,因为至少该位置是由标准解决的.

But from a language-lawyer perspective, I think we can call the behavior here undefined by omission. It's undefined simply because the standard doesn't address it. So going back to my opening statement, I'd add them to be on the safe side, because at least then the placement is addressed by the standard.

这篇关于我应该声明我的功能模板专长还是定义足够?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆