加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 为什么我的专用模板函数仅在调试版本中调用?

发布时间:2020-12-14 19:55:56 所属栏目:百科 来源:网络整理
导读:我在C 11 Xcode项目中有模板化函数,其中一些有专门化.但是,我发现专门化只能在调试版本中调用;如果我在发布中构建,它们将被忽略. 我已经成功创建了一个非常简单的例子: special.h #include cstdiostruct special{ templatetypename T void call(const T) {
我在C 11 Xcode项目中有模板化函数,其中一些有专门化.但是,我发现专门化只能在调试版本中调用;如果我在发布中构建,它们将被忽略.

我已经成功创建了一个非常简单的例子:

special.h

#include <cstdio>

struct special
{
    template<typename T>
    void call(const T&) { puts("not so special"); }
};

special.cpp

#include "special.h"
#include <string>

template<>
void special::call(const std::string&) { puts("very special"); }

main.cpp中

#include "special.h"
#include <string>

int main()
{
    std::string str = "hello world";
    special s;
    s.call(123);
    s.call(str);
}

You can download the project(至少在2013年夏天的某个地方)如果您不想自己创建它,则重现该问题.首先使用调试配置运行项目,然后在发布中再次运行它.我期望的输出是:

not so special
very special

这确实是我在Debug构建配置中得到的.但是,有了Release,我得到了这个:

not so special
not so special

这意味着忽略了special.cc中special :: call的专门实现.

为什么结果不一致?我该怎么做才能确保在发布版本中调用专用函数?

解决方法

你的程序有UB.在使用之前,必须显示明确的特化或至少其声明. [temp.expl.spec]§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.

将此声明添加到special.h:

template<>
void special::call(const std::string&);

或者,您可以将专业本身放入标题中.但是,由于专门化不再是模板,它遵循正常的函数规则,如果放在标题中,则必须标记为内联.

另外,请注意,函数模板特化具有相当特定的行为,并且通常使用重载比特化更好.有关详情,请参见Herb Sutter’s article.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读