Difference between struct and class when Template meta-programming - c++

template<int n>
struct Numberim{
enum{ value = Numberim<n-1>::value + n };
};
template<>
struct Numberim<0>{
enum{ value = 0 };
};
this is a simple tmp example,and it's ok;
template<int n>
class Numberim{
enum{ value = Numberim<n-1>::value + n };
};
template<>
class Numberim<0>{
enum{ value = 0 };
};
I use g++ to compile,and it complains...however, as far as I know, struct and class is treated nearly in the same way.just like this"In C++, the only difference between a struct and a class is that struct members are public by default, and class members are private by default."
So, what's the difference between them here in earth?

The difference will be same as it would be for typically class vs struct. Your "value" will be public for your first example (using struct) and private for your second example (using class).
For a reference on the difference between a class and a struct, please see What are the differences between struct and class in C++.

Concrete class Numberim<1> is not related to concrete class Numberim<0>.
Thus, having one class refer to the other’s definition of value works when value is public, which it is for the struct, but not when value is private, which it is for the class.
You can use the friend mechanism, or you can make value public, or you can, much more simply, do this:
template<int n>
class Numberim{
enum{ value = n*(n+1)/2 };
// And whatever else you want in here.
};

The difference is still the same, when it tries to compile Numberim<n-1>::value with n=1 it tries to use the template specialization. However, since value is private member of Numberim<0> (as the class member variables are private by default) it gives the compiler error.

Related

Why should you check if Base is a private or protected base of Derived?

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?
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.
Your assumptions are wrong.
std::is_convertible covers way more use cases than std::is_base_of.
It also works for user-defined conversion operator as well as
primitives.
https://gcc.godbolt.org/z/JULbVf
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.
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.

C++ CRTP And Incomplete Class Definition

Is referring to derived class fields allowed in base definition when using CRTP?
template<typename T>
class Base
{
public:
constexpr int IntInDerived = T::SomeInt; // <--- Is This Valid
using TypeInDerived = typename T::SomeType; // <--- Is This Valid
};
class Derived : public Base<Derived>
{
public:
constexpr int SomeInt = 10;
using SomeType = float;
};
I'm not sure because even though T::SomeInt and T::SomeType are dependent names, at moment Base is instantiated Derived is considered an incomplete type.
Apparently these are not valid when placed inside class definition block like in the question. However accessing T's members inside a method would be valid since methods are separately instantiated later.

boost::is_same with templated base class

I'm puzzled by the following problem. I want to write some trait struct in order to test if a certain class is derived from another. This can be solved with boost::is_base_of<>. However, the base class I want to test against has a free undefined template parameter.
Here is some code example:
template<typename T> class Base {};
class IntDeriv : Base<int> {};
class Foo {};
template< class TestClass >
struct is_derived_from_Base {
// how to create something that does the following and forces the compiler to deduce T
static const bool value = boost::is_base_of< Base<T> , TestClass >::value;
};
int main() {
cout << is_derived_from_Base<Foo> << endl; // should print 0
cout << is_derived_from_Base<IntDeriv> << endl; // should print 1
}
The problem is how to deduce T for Base<T> inside is_base_of.
Is this possible at all? I smell some enable_if but I'm not sure how to put it together.
What you want is possible. The trick used is possible in C++03, but as you didn't specify I will give you the C++11 version (using decltype, not available in C++03):
template<class TestClass>
struct is_derived_from_Base
{
template<typename T>
static std::true_type inherited(Base<T>*);
static std::false_type inherited(void*);
static const bool value = decltype(inherited(new TestClass()))::value;
};
You can see a live version here.
So, how does it works ?
When the struct is instantiated and value is needed, the compiler will get the return type of inherited(new TestClass()). This will call the appropriate function: if TestClass inherits Base<T>, then TestClass* (returned by new) is castable to Base<T>*, T being automatically deduced by the compiler. The return type is std::true_type. If TestClass does not inherits Base<T>, then the other overload is choosen, and the return type is std::false_type. The rest is straightforward: std::true_type::value = true and std::false_type::value = false.
There are still some corner cases:
Using private inheritance results in a compile error. I do not know how to solve it, because I don't know the answer: if A privately inherits B, is A derived from B or not ? (in general, private inheritance is considered as an implementation inheritance). Also note that in this case, A* a = new B(); will not compile.
Using a private constructor prevents the previously explained trick from working correctly. It will result in a compile-time error. Since this defeats the whole point of this method, you will have to find another way for such classes.
Note you have to use it the following way: is_derived_from_Base<Foo>::value, not as you've written (is_derived_from_Base<Foo>).

Avoid repeating the template parameter for accessing enum in class template

Consider a class template that implements a container which includes an option for choosing its storage place.
template<class T>
class Container {
public:
enum StorageOption {A,B};
Container(StorageOption opt_): option(opt_) {}
private:
StorageOption option;
};
Here StorageOption was chosen to be a member since it is only used in the class.
Now, to instantiate the class I would need to repeat the template parameter, like:
{
Container<int> c( Container<int>::A );
}
Is there a way to avoid repeating the parameter and at the same time have StorageOption being a member or is there a better way of implementing the option?
It is usually achieved by defining it in a base class.
class ContainerBase {
public:
enum StorageOption {A,B};
};
template<class T>
class Container : public ContainerBase{
public:
Container(StorageOption opt_): option(opt_) {}
private:
StorageOption option;
};
Container<int> c( ContainerBase::A );
I have been battling with this problem myself and I don't really like the need for a base class as well as how you need to repeat the base class specifier when wanting to use enum classes. I came up with this solution:
namespace FuncEnum{
enum class FuncNeighbor{
FLOOR, CEILING, SELF
};
enum class FuncDirection{
BACK, FRONT, BACKNFRONT
};
enum class FuncVar{
X, Y
};
} using namespace FuncEnum;
template<typename... Types>
class Func {};
This way you can have globally available enum classes with minimal specification. It's not likely that collision happens between < class nickname > < enum class name > but even if there were, the using declaration should shadow (?) whatever global identifier about to interfere (which, in a peculiar case can be undone again with another using declaration).

Are struct in c++ similar to enum or classes?

I am wondering if a struct has the same idea as enum in c++? If someone can explain similarities/differences I will be grateful I am trying to learn.
Are struct in c++ similar to enum or classes?
In C++, a struct is essentially the same as a class, except that the default access modifiers for member variables, methods, and for base classes are all public, where in a class, the default access modifier is private.
struct is basically a class with all members public.
For instance:
struct MyNewStruct {
int myNewInt;
double myNewDouble;
};
is equivalent to:
class MyNewClass {
public:
int myNewInt;
double myNewDouble;
};
Hence, you can create a struct with constructor:
struct MyNewStruct {
int myNewInt;
double myNewDouble;
MyNewStruct(int i, double d)
: myNewInt(i), myNewDouble(d)
{}
};
An enum is for abstracting away magic numbers.
A struct is for holding a collection of different variables.
You can almost think of an enum as a stand-in for an int or char to make things more readable.