Reputation: 22183
This is my code:
template<class V, class Ref = V&>
class Util {
public:
typedef Ref reference;
};
template<class D, class V, class Ref = V&>
class Base {
public:
class Inner1: public Util<const V, const Ref> {
public:
Inner1(const D &d) :
d(d) {
}
typename Inner1::reference foo() const {
static V v;
return v;
}
private:
const D &d;
};
class Inner2: public Util<V, Ref> {
public:
Inner2(D &d) :
d(d) {
}
typename Inner2::reference foo() const {
static V v;
return v;
}
private:
D &d;
};
};
class Child: public Base<Child, float> {
public:
Inner1 getInner1() const {
return Base<Child, float>::Inner1(*this);
}
Inner2 getInner2() {
return Base<Child, float>::Inner2(*this);
}
};
void print(float & ff) {
}
int main() {
Child c;
Child::Inner1 inner = c.getInner1();
print(inner.foo());
return 0;
}
This code compile without problems but I guess I should receive a compilation error. The method foo of class Inner1
should return a const
reference, but for unknown reason Ref
is defined without const
. Why?
Upvotes: 1
Views: 52
Reputation: 170153
but for unknown reason Ref is defined without const. Why?
Leading const is misleading. In the type Util<const V, const Ref>
you const
qualify the Ref
type. I.e., you supposedly pass V & const
as the type, and not V const &
. While normally V & const
would be ill-formed, when dealing with the type indirectly, such as when it's aliased or a template argument, the extra cv-qualifier is simply ignored.
Personally, I would use the extra template parameter for an entire trait.
template<class V>
class VTrait {
public:
typedef V & reference;
typedef V const & const_reference;
};
template<class D, class V, class Trait = VTrait<V>>
class Base {
public:
class Inner1: public Util<const V, typename Trait::const_reference> {
// ...
};
// ...
};
Client code that wants something different from your framework will need only customize the Trait
.
Upvotes: 2
Reputation: 172954
const Ref
, given Ref
is V&
, i.e. float&
, note that const
is qualified on the reference itself, not the type being referenced. The const
qualifier is just omitted, you're still getting V&
, but not const V&
as you expected. (To be precise there's no const
references in C++ but only references to const
or to non-const
.)
If you change const Ref
to const V&
(i.e. reference to const
), you'll get the error you expected. e.g.
class Inner1: public Util<const V, const V&> {
...
Upvotes: 1