The only difference between std::is_base_of<Base, Derived>
and std::is_convertible<Derived*, const volatile Base*>
is that the former is true also when Base
is a private or protected base class of Derived
. But, when do you really need to know if Base
is a private or protected base? Why should the user care about internal implementation of a class?

- 1,559
- 9
- 15
3 Answers
As one example, consider
template <typename T>
struct Foo : T, Bar {};
In this case it is no longer an implementation detail whether T
does inherit from Bar
(or any other class) even if the inheritance is protected.
For private inheritance, consider a base class that does some book-keeping. For example creating log entries every time an instance is created. Now again, when I inherit from a second type as in template <typename T> struct Foo : T {};
I want to know if T
already inherits from the bookkeeping class or if I have to add that myself.

- 109,796
- 11
- 89
- 185
Your assumptions are wrong.
std::is_convertible
covers way more use cases thanstd::is_base_of
.It also works for user-defined conversion operator as well as primitives.
If a class privately inherits a Base class that's not an internal implementation detail, but has effect on the public interface of the class. For example the fact that conversion to the base class is prevented.

- 5,700
- 1
- 19
- 49
-
1i dont really understand your second point. If a class does not inherit from `Base` you also cannot convert to `Base`. Whats the difference? – 463035818_is_not_an_ai May 26 '20 at 09:25
-
You might want to check out use cases for private inheritance. https://www.bogotobogo.com/cplusplus/private_inheritance.php https://stackoverflow.com/questions/656224/when-should-i-use-c-private-inheritance – Simon Kraemer May 26 '20 at 09:43
-
i think I know what is private inheritance. I think the misunderstanding is, it is an implementation details when a class inherits privately while I suppose your interpretation is: It is not an implementation details whether inheritance is private or public. Consider you get a `struct Foo : private Bar {};` then from the public interface you cannot tell if `Foo` does inherit from `Bar` or not. – 463035818_is_not_an_ai May 26 '20 at 09:46
-
I didn't say that there is only one difference between `std::is_base_of` and `std::is_convertible`, I said that there is only one difference between `std::is_base_of
` and `std::is_convertible `. As idclev 463035818 pointed out, conversion from `Base*` to `Derived*` is allowed if **and only if** `Base` is a public and unambiguous base of `Derived`, in any other case the conversion is always prevented – user7769147 May 26 '20 at 17:21
The following class:
class C
{
operator int() { return 0; }
};
is convertible to int:
constexpr bool is_int = std::is_convertible_v<C, int>; // true
Yet int is not the base of C:
constexpr bool is_base = std::is_base_of_v<int, C>; // false
So your premise, that the only reason for these functions to exist is:
But, when do you really need to know if Base is a private or protected base? Why should the user care about internal implementation of a class?
is incorrect. There are other use cases.

- 5,076
- 2
- 22
- 31
-
I didn't say that there is only one difference between `std::is_base_of` and `std::is_convertible`, I said that there is only one difference between `std::is_base_of
` and `std::is_convertible `. Furthermore, `constexpr bool is_base = std::is_base_of – user7769147 May 26 '20 at 17:14;` is not an error, its value is defined and it's false! -
@user7769147 You start out the question with: "The only difference between ..." that looks to me like "one". Anyway, You're right about `is_base_of`, it should be `is_base_of_v` to fix the compilation error. – Robert Andrzejuk May 27 '20 at 13:08