首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gcc用专门的定义内联泛型模板函数。

gcc用专门的定义内联泛型模板函数。
EN

Stack Overflow用户
提问于 2017-05-03 02:22:37
回答 1查看 581关注 0票数 0

我怀疑gcc 4.8.3是否插入了错误的模板函数.此问题不发生在调试模式中,而是仅在优化模式下发生。然而,这发生在一个复杂的代码库中,我无法在一个简单的测试用例中重现这个问题。

我的代码如下所示

代码语言:javascript
运行
复制
#include "stdio.h"

class A {
 public:

    template<typename T> int WriteNative(const T) { 
      printf("here?\n")
      return 0; 
    }

    template<typename D> 
        void doit() {
        if (WriteNative<double>(1)) {
            printf("A\n");
        } else {
            printf("B\n");
        }
    }

};

// in my real code, this definition is in a different cpp file
template<> int A::WriteNative<double>(const double) { 
  return 1; 
}

int main() {
    A a;
    a.doit<float>();
}

在调试生成中,它打印出A,而在优化构建中,它在这里打印出?\nB

我想任何内联都使用泛型模板函数定义,而不是专用模板函数定义。但是属性 ((noinline))没有帮助。

如果我的代码有定义的C++行为,还有人吗?以及如何解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2017-05-03 04:13:56

您没有显式地声明这一点,但在实际代码中,我猜您没有在A的.h文件中声明专门化。因此,当A.h包含在单独的编译单元中时,编译器不知道WriteNative()的专门化。添加专门化声明应该可以解决这个问题,而不必将定义包含在同一个文件中(即不必内联):

代码语言:javascript
运行
复制
class A {
    public:
    template<typename T> int WriteNative(const T) { 
      printf("here?\n")
      return 0; 
    }

    template<typename D> 
        void doit() {
        if (WriteNative<double>(1)) {
            printf("A\n");
        } else {
            printf("B\n");
        }
    }
};
template<> int A::WriteNative(const double);

您可以通过使用三个文件( A.hA.cppmain.cpp )来再现问题,其中A.cpp包含专门化的定义,因此当main.cpp包含A.h时,它不知道在优化期间发生内联时的专门化,而使用-O0编译时不会出现内联,因此WriteNative()将根据A.cpp中的定义进行链接。

编辑:看这个answer,它引用了规范来解释为什么这是正确的行为。

14.7.3 temp.expl.spec

6如果模板、成员模板或类模板的成员明确地专门化,则应在首次使用该专门化之前声明该专门化,这将导致在发生这种使用的每个翻译单元中进行隐式实例化;不需要进行诊断。如果程序没有为显式专门化提供定义,并且使用专门化的方式会导致隐式实例化发生,或者成员是虚拟成员函数,则程序是格式错误的,不需要诊断。不为声明但未定义的显式专门化生成隐式实例化。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43750053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档