标签: name-hiding

模板参数名称隐藏

我最近被咬了(简化)

struct Base {
    typedef char T;
};

template<typename T>
struct Foo : Base {
    T x[50];  // This is Base::T, not the template parameter
};
Run Code Online (Sandbox Code Playgroud)

换句话说,类成员名称隐藏模板参数(即使来自基类,因此在本地上下文中并不完全明显).

然而,我做了一些实验,发现:

struct Base {
    typedef char T;
};

template<typename T, typename B>
struct Foo : B {
    T x[50];  // This T is the template parameter,
              // even passing Base as B
};
Run Code Online (Sandbox Code Playgroud)

这个显然荒谬的规则背后的理由是什么(如果有的话)?

我能想到的唯一出路是给出丑陋的模板参数名称,也意味着在不使用保留名称的情况下安全地编写模板是不可能的(因为模板中使用的类可能会碰撞参数名称...请注意很多C++代码使用uglyfied名称为私人成员).

PS:我没有深入研究这个问题的标准,但g ++和clang ++都同意这个行为,所以我不认为这是一个bug.

PPS:在实际代码中,隐藏的模板参数被命名tid,并且是整数而不是类型.-Wall还没有足够的关于隐藏的问题,我在用valgrind进行了几个小时的调试后发现了它.

c++ templates language-lawyer name-lookup name-hiding

14
推荐指数
1
解决办法
514
查看次数

为什么类成员函数具有相同名称的阴影自由函数?

最近我注意到,当在类中时,成员函数完全使用相同名称的阴影函数.完全我的意思是,每个具有相同名称的自由函数根本不考虑重载解析.我能理解为什么用这样的事情来完成它:

void f();

struct S
{
    void f();

    void g()
    {
        f(); // calls S::f instead of ::f
    }
};
Run Code Online (Sandbox Code Playgroud)

在函数具有相同签名的情况下,其唯一自然的变量作用域以相同的方式工作.但是为什么要禁止自由函数具有不同签名的无意义调用:

void f();

struct S
{
    void f(int x);

    void g()
    {
        f(); // fails to compile attempting to call S::f, which has wrong signature
    }
};
Run Code Online (Sandbox Code Playgroud)

我不是问如何从类中调用一个带阴影的自由函数.我想知道的是这种设计背后的基本原理.

c++ overloading member-functions name-lookup name-hiding

10
推荐指数
1
解决办法
2497
查看次数

重载超类的功能

C++标准中有什么东西阻止我重载超类的功能吗?

从这对课开始:

class A {            // super class
    int x;

public:
    void foo (int y) {x = y;}  // original definition
};

class B : public A { // derived class
    int x2;

public:
    void foo (int y, int z) {x2 = y + z;}  // overloaded
};
Run Code Online (Sandbox Code Playgroud)

我可以B::foo()轻松打电话:

    B b;
    b.foo (1, 2);  // [1]
Run Code Online (Sandbox Code Playgroud)

但如果我试着打电话A::foo()......

    B b;
    b.foo (12);    // [2]
Run Code Online (Sandbox Code Playgroud)

...我收到编译器错误:

test.cpp: In function 'void bar()':
test.cpp:18: error: no matching function for call …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance overloading name-hiding

9
推荐指数
1
解决办法
4258
查看次数

警告:重载的虚函数"Base :: process"仅在类"derived"中被部分覆盖

我低于警告.我的部分代码是:

class Base {
public:
    virtual void process(int x) {;};
    virtual void process(int a,float b) {;};
protected:
    int pd;
    float pb;
};

class derived: public Base{
public:
    void process(int a,float b);
}

void derived::process(int a,float b){
    pd=a;
    pb=b;
    ....
}
Run Code Online (Sandbox Code Playgroud)

我收到以下警告:

 Warning: overloaded virtual function "Base::process" is only partially overridden in class "derived"
Run Code Online (Sandbox Code Playgroud)

我以任何方式将进程作为虚函数,所以我期待这个警告不应该来......这背后的原因是什么?

c++ overriding virtual-functions name-hiding

8
推荐指数
2
解决办法
4431
查看次数

关于名称隐藏和虚拟功能的困惑

提到另一个问题

考虑一下代码:

class Base {
public: 
    virtual void gogo(int a){
        printf(" Base :: gogo (int) \n");
    };

    virtual void gogo(int* a){
        printf(" Base :: gogo (int*) \n");
    };
};

class Derived : public Base{
public:
    virtual void gogo(int* a){
        printf(" Derived :: gogo (int*) \n");
    };
};

int main(){

    // 1)       
    Derived * obj = new Derived ; 
    obj->gogo(7);  // this is illegal because of name hiding


    // 2)      
    Base* obj = new Derived ;
    obj->gogo(7); // this …
Run Code Online (Sandbox Code Playgroud)

c++ virtual overriding name-hiding

6
推荐指数
2
解决办法
2587
查看次数

变量名称与函数名称相同,给出编译器错误...为什么?

今天进入一个有趣的问题,我试图理解为什么.

考虑以下:

class Base
{
public:
    Base(){}
    ~Base(){}
    static void function1(){}
        void function2()
        {
           int function1;
           function1 = 0;
           function1();   //<-compiler error
           function1 = 1;
        }
};
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

表观调用括号前的表达式必须具有(指向 - )函数类型

我想我明白为什么我收到这个错误:

  1. function1它本身被调用时function2(),它实际上是一个函数指针function1().

  2. 里面的范围function2,当int function1被宣布," function1变"阴影" function1函数指针".

  3. function1()在内部调用时function2(),它假定function1是变量并且给出错误.

  4. 通过调用Base::function1();内部来解决这个问题function2().

我的问题是:为什么编译器在声明时没有出错int function1;?这不应该被允许吗?

c++ scope declaration name-lookup name-hiding

5
推荐指数
1
解决办法
1530
查看次数

在C ++ 14中继承模板化的operator =:g ++和clang ++的不同行为

我有这段代码可以在GCC 9.1中正常工作:

#include <type_traits>

template< typename T >
class A
{
protected:
    T value;

public:
    template< typename U,
              typename...,
              typename = std::enable_if_t< std::is_fundamental< U >::value > >
    A& operator=(U v)
    {
        value = v;
        return *this;
    }
};

template< typename T >
class B : public A<T>
{
public:
    using A<T>::operator=;

    template< typename U,
              typename...,
              typename = std::enable_if_t< ! std::is_fundamental< U >::value > >
    B& operator=(U v)
    {
        this->value = v;
        return *this;
    }
};

int main()
{
    B<int> obj; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer overload-resolution name-hiding c++14

5
推荐指数
1
解决办法
145
查看次数

从纯虚类(A)派生的指针无法访问纯类(B)的重载方法

考虑我有两个纯虚拟类,一个派生自另一个,一个具体类派生自最后一个:

#include <iostream>
#include <string>

class Abstract1
{
public:
    virtual ~Abstract1() { };
    virtual void method(int a) = 0;

protected:
    Abstract1() = default;
};

class Abstract2: public Abstract1
{
public:
    virtual ~Abstract2() { };
    virtual void method(char c, std::string s) = 0;

protected:
    Abstract2() = default;
};

class Concrete : public Abstract2
{
public:
    void method(int a) override
    {
        std::cout << __PRETTY_FUNCTION__ << "a: " << a << std::endl;
    }

    void method(char c, std::string s) override
    {
        std::cout << __PRETTY_FUNCTION__ …
Run Code Online (Sandbox Code Playgroud)

c++ pure-virtual name-hiding c++11

5
推荐指数
1
解决办法
82
查看次数

如何在派生类中访问基类中的所有隐藏名称?

从这个问题开始:

并考虑这个简化的代码:

#include <string>
#include <iostream>

class Abstract
{
public:
    virtual void method(int a)
    {
        std::cout << __PRETTY_FUNCTION__ << "a: " << a << std::endl;
    }
};

class Concrete : public Abstract
{
public:
    void method(char c, std::string s)
    {
        std::cout << __PRETTY_FUNCTION__ << "c: " << c << "; s: " << s << std::endl;
    }
};

int main()
{
    Concrete c;
    c.method(42);    // error: no matching function for call to 'Concrete::method(int)'
    c.method('a', std::string("S1_1"));

    Abstract *ptr = &c; …
Run Code Online (Sandbox Code Playgroud)

c++ using-declaration name-lookup name-hiding

5
推荐指数
0
解决办法
97
查看次数

对虚函数和派生类的混淆

我想了解下面的代码:

#include<iostream>
using namespace std;
class Base {
    public:
        virtual void f(float) { cout << "Base::f(float)\n"; }
};
class Derived : public Base {
    public:
        virtual void f(int) { cout << "Derived::f(int)\n"; }
};
int main() {
    Derived *d = new Derived();
    Base *b = d;
    d->f(3.14F);
    b->f(3.14F);
}
Run Code Online (Sandbox Code Playgroud)

这打印

Derived::f(int)
Base::f(float)
Run Code Online (Sandbox Code Playgroud)

我不确定为什么.

第一个调用d-> f(3.14F)调用Derived中的函数f.我不是100%肯定为什么.我看了一下(http://en.cppreference.com/w/cpp/language/implicit_cast),其中说:

浮点类型的prvalue可以转换为任何整数类型的prvalue.小数部分被截断,即,小数部分被丢弃.如果该值不适合目标类型,则行为未定义

对我来说,你不能这样做,因为浮点数不适合int.为什么允许这种隐式转换?

其次,即使我只接受上面的判断,第二次调用b-> f(3.14F)也没有意义.b-> f(3.14F)正在调用虚函数f,因此动态解析它以调用与b指向的对象的动态类型相关联的f(),这是一个Derived对象.因为我们被允许将3.14F转换为int,因为第一个函数调用表明这是合法的,这(我的理解)应该再次调用Derived :: f(int)函数.然而它调用了Base类中的函数.那么为什么呢?

编辑:这是我如何理解并向自己解释的.

b是指向Base对象的指针,因此我们只能使用b来访问Base对象的成员,即使b确实指向某个Derived对象(这是标准的OO /继承内容).

此规则的唯一例外是Base的成员函数声明为virtual.在这种情况下,Derived对象可以覆盖此函数,通过使用完全相同的签名提供另一个实现.如果发生这种情况,那么即使我们碰巧通过指向Base对象的指针访问成员函数,也会在运行时调用此Derived实现.

现在,在上面的代码片段中,我们没有任何重写,因为B :: f和D :: f的签名是不同的(一个是浮点数,另一个是int).因此,当我们调用b-> f(3.14F)时,唯一考虑的函数是原始的B :: f,这就是所谓的.

c++ virtual-functions name-hiding

4
推荐指数
1
解决办法
1498
查看次数