Reputation: 2614
I understand that I can't use the result of getValue()
in a switch
statement because the case tree is built at compile time.
What I have is a class which contains static const
members that have a constant value set at runtime from a constructor. The value to be set is always known at compile time.
Is it possible to use templates or some other solution to define these const
objects in a type safe manner and keep them as static members of a class?
Note that I do NOT want an enum
in this case as I want to switch on different types such as an int
in the following example.
Example:
#include <iostream>
using namespace std;
class Some_Class {
private:
int _value;
public:
Some_Class(int value) {
_value = value;
}
int getValue() const {
return _value;
}
static const Some_Class ONE;
static const Some_Class TWO;
}; // class
const Some_Class Some_Class::ONE(1);
const Some_Class Some_Class::TWO(2);
int main() {
int value = 1;
switch (value) {
case Some_Class::ONE.getValue():
cout << "Do thing 1" << endl;
break;
case Some_Class::TWO.getValue():
cout << "Do thing 2" << endl;
}
return 0;
}
This does not work for the aforementioned problem:
main.cpp(29) : error C2051: case expression not constant
main.cpp(32) : error C2051: case expression not constant
Upvotes: 0
Views: 1054
Reputation: 4637
Something similar can be done, provided the constructor can be constexpr
and the class can be inherited. Since we can't have static constexpr Some_Class
as a member of Some_Class
, we get around that with a derived class.
#include <iostream>
namespace detail
{
class Base_Class //Has the functionality
{
private:
int _value;
public:
constexpr Base_Class(int value) : _value(value) {}
constexpr int getValue() const
{
return _value;
}
};
}
//Inherits functionality, has static members
class Some_Class : public detail::Base_Class
{
public:
using Base_Class::Base_Class;
static constexpr Base_Class ONE{1};
static constexpr Base_Class TWO{2};
};
int main()
{
int value = 1;
switch (value)
{
case Some_Class::ONE.getValue():
std::cout << "Do thing 1" << std::endl;
break;
case Some_Class::TWO.getValue():
std::cout << "Do thing 2" << std::endl;
}
return 0;
}
Upvotes: 4