ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C用模板和虚函数标记疯狂

2019-07-22 18:08:00  阅读:199  来源: 互联网

标签:c templates g clang-2


在重构一个相当大的代码库的过程中,我的编译器想出了一个误解我的好方法.这是我所说的最简单的例子:

#include <iostream>

class Foo {
public:
        virtual int get() = 0;
        template <typename T> int get(int i) { return 4 + i; }
};

class Bar : public Foo {
public:
        virtual int get() { return 3; }
};

int main(int argv, char **argc) {
        Bar b;
        std::cout << b.get<char>(7) << std::endl;
        return 0;
}

Clang 3.6,gcc 4.7,gcc 4.8和gcc 4.9都将“b.get(7)”标记为“b.get”和“char”之间的比较运算符.

template-test.cpp: In function ‘int main(int, char**)’:
template-test.cpp:16:17: error: invalid use of non-static member function
  std::cout << b.get<char>(7) << std::endl;
                 ^
template-test.cpp:16:21: error: expected primary-expression before ‘char’
  std::cout << b.get<char>(7) << std::endl;
                     ^

(这是gcc 4.9,其他人说类似的东西)

这应该有用吗?

我找到的解决方法是在基类和派生类中声明模板化的“get”.

解决方法:

派生类中的名称get隐藏了基类中的名称get.因此,在执行名称查找时找不到函数模板get(),并且编译器只能以您看到的方式解释这些令牌.

您可以在Bar类中使用using声明来修复它:

class Bar : public Foo {
public:
    using Foo::get;
//  ^^^^^^^^^^^^^^^
    virtual int get() { return 3; }
};

这是一个live demo on Coliru.

如果您无法修改Bar的定义,因为它不在您的控制之下,我猜您可以将调用限定为get():

std::cout << f.Foo::get<char>(7) << std::endl; // get() template is found now.

有关现场演示,请参阅here.另一种选择是通过指针或对Foo的引用来执行调用:

Bar b;
Foo& f = b;
std::cout << f.get<char>(7) << std::endl; // get() template is found now.

再一次,live example.

标签:c,templates,g,clang-2
来源: https://codeday.me/bug/20190722/1505373.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有