I want the class member can be changed depending on the template args. I want something like follow
template<int value>
class MyClass
{
public:
void print()
{
// using the member
std::cout << sizeData() << std::endl;
for (int i=0;i<sizeData();i++)
{
std:cout << data[i] << std::endl;
}
}
static int sizeData()
{
#if value == 1
return 3;
#endif
#if value == 2
return 6;
#endif
}
static int sizeArray()
{
#if value == 1
return 40;
#endif
#if value == 2
return 200;
#endif
}
private:
#if value == 1
int data[3];
const static int array[40];
#endif
#if value == 2
int data[6];
const static int array[200];
#endif
}
I do not know can it be implemented in c++.
Thanks for your time.
Many sir already give the answer in C++11 and C++17. Thanks all your's advises.
If the code can be settled in C++98, it will be perfect. Because my code should run on a platform which only support C++98.
You can use std::conditional
to pick which member you would like to have like
template<int value>
class MyClass
{
public:
static int sizeData()
{
return (value == 1) ? 3 : 6; // needs to be improved
}
static int sizeArray()
{
return sizeof(array) / sizeof(array[0]); // size of array divided by size of element is then number of elements in the array
}
private:
std::conditional_t<value == 1, int[3], int[6]> data;
const static std::conditional_t<value == 1, int[40], int[200]> array;
};
While std::conditional
is not a part of C++98, it's implemented only using C++98 C++, so you can make you own using the possible implementation from the reference site link. You can see that working with
#include <iostream>
template<bool B, class T, class F>
struct conditional { typedef T type; };
template<class T, class F>
struct conditional<false, T, F> { typedef F type; };
template<int value>
class MyClass
{
public:
static int sizeData()
{
return (value == 1) ? 3 : 6; // needs to be improved
}
static int sizeArray()
{
return sizeof(array) / sizeof(array[0]);
}
private:
typename conditional<value == 1, int[3], int[6]>::type data;
const static typename conditional<value == 1, int[40], int[200]>::type array;
};
int main()
{
MyClass<1> m;
std::cout << m.sizeData();
}
in this live example.
This kind of falls apart for sizeData
since data
is not static
but the function is. To avoid code duplication, instead of using std::conditional
, we can use the enum trick to get compile time constants for the sizes of the array and use that like
#include <iostream>
template<int value>
class MyClass
{
public:
static int sizeData()
{
return data_size; // now improved
}
static int sizeArray()
{
return array_size;
}
private:
enum { data_size = (value == 1) ? 3 : 6 }; // this is required to be a compile time constant
enum { array_size = (value == 1) ? 40 : 200 }; // these need to become before the array members
int data[data_size]; // less verbose
const static int array[array_size];
};
int main()
{
MyClass<1> m;
std::cout << m.sizeData();
}
You can use if constexpr
and immediately evaluated constexpr lambdas
.
Disclaimer: it is C++ 17 only, need extra brackets that enclose the lambda in order to compile, and I really wouldn't recommend to use this code as it is. It's purpose is demonstration only!
template<int value>
class MyClass
{
public:
static int sizeData()
{
if constexpr(value == 1)
return 3;
if constexpr (value == 2)
return 6;
}
static int sizeArray()
{
if constexpr (value == 1)
return 40;
if constexpr (value == 2)
return 200;
}
private:
int data[([](int v) constexpr { if (v == 1) return 3; if (v==2) return 6; }(value))];
const static int array[([](int v) constexpr { if (v == 1) return 40; if (v==2) return 200; }(value))];
};
int main()
{
MyClass<1> m1;
MyClass<2> m2;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With