Name Lookup and class scope

2019-02-19 18:00发布

问题:

Why is it that the return type of setVal is of type string and the parameter type is of type double

typedef string Type;
Type initVal(); 
class Exercise {
public:
    typedef double Type;
    Type setVal(Type); 
    Type initVal(); 
private:
    int val;
};

Type Exercise::setVal(Type parm) {  
    val = parm + initVal();    
    return val;
}

回答1:

When member functions are defined in namespace scope C++ provides special name lookup rules for unqualified names that follow the function’s declarator-id (3.4.1/8). Such names are looked up in class scope before they are looked up in namespace scope.

Since the return type in an "ordinary" member function definition precedes function’s declarator-id, the aforementioned special rules do not apply to it. It is looked up in accordance with the "usual" rules: in namespace scope.

For this reason your function definition's return type refers to ::Type, not to Exercise::Type. It does not match any of the declarations made inside the class. The code is ill-formed.

If you want the unqualified return type name to be looked up in class scope as well, use the new trailing return type syntax in function declaration, since in this syntax the return type follows function’s declarator-id

auto Exercise::setVal(Type parm) -> Type {  
    val = parm + initVal();    
    return val;
}


回答2:

That code doesn't compile, and I'm having trouble teasing out what it's supposed to do, but I think the answer to your question is that the parameter is of type Exercise::Type, while the return value is of type ::Type, the global typedef. If you want them to match, when you define setVal outside the class definition, you need to fully specify the return value as Exercise::Type, as so:

typedef string Type;

class Exercise {
public:
    typedef double Type;
    Type setVal(Type);
    Type initVal() { return 1.0; }
private:
    int val;
};

Exercise::Type Exercise::setVal(Type parm) {
    val = parm + initVal();
    return val;
}


回答3:

Because local variable will cover global variable automatically.