简体   繁体   中英

Why derived class cannot be used in place of base class, as a template parameter?

In the following snippet, I have a template function foo() that takes a pointer to some object as a template argument.

class P {};
class Q : public P {};

P p;
Q q;

template <P*> void foo() {}

void test() {
  foo<&p>();
  foo<&q>();
}

According to the documentation, this should work provided that

For pointers to objects, the template arguments have to designate the address of a complete object with static storage duration and a linkage (either internal or external), or a constant expression that evaluates to the appropriate null pointer or std::nullptr_t value.

Since the object in question must have static storage duration, I define it globally. However, the compiler complains about the second invocation of foo() :

test.cc:66:7: error: no matching function for call to 'foo'
      foo<&q>();
      ^~~~~~~
test.cc:62:26: note: candidate template ignored: invalid
explicitly-specified argument for template parameter 'p'
    template <P* p> void foo() {}

I don't understand why is this happening, and why such usage is forbidden?

the template arguments have to designate the address of a complete object with static storage duration

A base class subobject is not a complete object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM