I am trying to implement an enum class that behaves like the one introduced with C++11 (with type safety etc.) but that also behaves as a real class (with constructor, method, etc.). In order to do so, I kept the internal enum anonymous: this had the side effect that in order to keep m_value as a private member variable, I had to add a static member variable named _, as you can see below:
#include <iostream>
#include <experimental/string_view>
class State
{
public:
static enum
{
UNKNOWN,
STARTED,
STOPPED
} _;
private:
using Type = decltype( _ );
Type m_value;
public:
constexpr State( Type value = UNKNOWN )
: m_value( value )
{ }
constexpr bool operator==( Type value ) const
{
return m_value == value;
}
constexpr std::experimental::string_view to_string( ) const
{
switch ( m_value )
{
case UNKNOWN: return "UNKNOWN";
case STARTED: return "STARTED";
case STOPPED: return "STOPPED";
}
return "";
}
};
State::Type State::_;
int main( )
{
State state;
std::cout << state.to_string( ) << std::endl;
state = State::STARTED;
std::cout << state.to_string( ) << std::endl;
if( state == State::STOPPED )
{
std::cout << state.to_string( ) << std::endl;
}
return 0;
}
Is there a way to get rid of the useless static member variable _? I would like to keep the internal enum anonymous, and somehow to fetch its type when required (= only privately).
How about simply use one of the enum values? e.g.:
//...
enum
{
UNKNOWN,
STARTED,
STOPPED
};
private:
using Type = decltype( UNKNOWN );
//...
[live demo]
Related
My intention was to use arbitrary functions as First Class Variables. I used the visitor pattern (at least i think that's what that is) to achieve effectively arbitrary functions as First Class Variables.
Is there a better way to achieve this?
Except for safety, is there a big drawback in this design?
Here is a minimal working example, using boost 1.76.0 and C++20 standard:
boost::variant<void*,int> rep (){
return 2;
}
boost::variant<void*,int> oll(){
std::cout << "happiness" << std::endl;
return nullptr;
}
boost::variant<void*,int> iuu(int a ){
return a;
}
class my_visitor : public boost::static_visitor<boost::variant<void*,int>>
{
public:
boost::variant<void*,int> operator()(boost::variant<void*,int>(*fun)() ) const
{
return fun();
}
boost::variant<void*,int> operator()(boost::variant<void*,int>(*fun)(int) ) const
{
return fun(argument);
}
int argument;
};
int main() {
boost::variant<boost::variant<void*,int>(*)(), boost::variant<void*,int>(*)(int)> varob(iuu);
my_visitor vis = my_visitor();
vis.argument = 22;
std::cout << boost::apply_visitor(vis, varob);
I want my functions to return either an indication of success or an object that describes the nature of the failure. I'd normally use exceptions for this but I've been told not to use them for common code paths and this set of functions can be expected to fail fairly often for various reasons.
My thought is to use C++17's std::optional as I don't have to return a full error object when it's not needed. So with optional, if the function doesn't succeed it returns the error object, otherwise the optional is empty. The issue with that is it reverses the expectation of a returned value (i.e. true usually indicates success not failure).
I could get people to use an is_success function, which would be used like this, assuming Error is my error class:
auto result = do_stuff();
if (!is_success(result)) {
Error err = *result;
// ...
}
Or would a result class be more robust?
class MaybeError {
std::optional<Error> _error;
public:
MaybeError(const Error& error) : _error(error) {}
constexpr MaybeError() : _error({}) {}
explicit operator bool const() {
return !(_error.operator bool());
}
constexpr bool has_error() const {
return !(_error.has_value());
}
constexpr Error& error() & { return _error.value(); }
constexpr const Error & error() const & { return _error.value(); }
constexpr Error&& error() && { return std::move(_error.value()); }
constexpr const Error&& error() const && { return std::move(_error.value()); }
constexpr const Error* operator->() const { return _error.operator->(); }
constexpr Error* operator->() { return _error.operator->(); }
constexpr const Error& operator*() const& { return _error.operator*(); }
constexpr Error& operator*() & { return _error.operator*(); }
constexpr const Error&& operator*() const&& { return std::move(_error.operator*()); }
constexpr Error&& operator*() && { return std::move(_error.operator*()); }
};
Which can be used similarly to the first example:
auto result = do_stuff();
if (!result) {
Error err = *result;
// ...
}
What is the best option? Am I going about this the right way?
Edit To be clear, the do_stuff function that's being called doesn't return an object if it succeeds. If it always succeeded without error it'd just be void do_stuff().
Edit 2 In the comments Christian Hackl suggests a less over-engineered solution using a simple struct.
struct MaybeError {
std::optional<Error> error;
};
This would be both simpler and address my concern that people would expect functions to return true if successful by making it explicit that it is the error condition that is being tested for. E.g.:
auto result = do_stuff();
if (result.error) {
Error e = *t.error;
// ...
}
I played around a bit with boost::expected that was suggested by Nicol Bolas. It seems to be really nice for this use case:
#include <iostream>
#include <system_error>
#include <boost/expected/expected.hpp>
using ExpectedVoid = boost::expected< void, std::error_code >;
using ExpectedInt = boost::expected< int, std::error_code >;
ExpectedVoid do_stuff( bool wantSuccess ) {
if( wantSuccess )
return {};
return boost::make_unexpected( std::make_error_code( std::errc::operation_canceled ) );
}
ExpectedInt do_more_stuff( bool wantSuccess ) {
if( wantSuccess )
return 42;
return boost::make_unexpected( std::make_error_code( std::errc::operation_canceled ) );
}
int main()
{
for( bool wantSuccess : { false, true } )
{
if( auto res = do_stuff( wantSuccess ) )
std::cout << "do_stuff successful!\n";
else
std::cout << "do_stuff error: " << res.error() << "\n";
}
std::cout << "\n";
for( bool wantSuccess : { false, true } )
{
if( auto res = do_more_stuff( wantSuccess ) )
std::cout << "do_more_stuff successful! Result: " << *res << "\n";
else
std::cout << "do_more_stuff error: " << res.error() << "\n";
}
return 0;
}
Output:
do_stuff error: generic:105
do_stuff successful!
do_more_stuff error: generic:105
do_more_stuff successful! Result: 42
You can download the source from the link at the beginning and just throw the files from the "include" directory of the source into your boost include directory ("boost" sub folder).
There are types designed for this. One proposed for standardization (PDF) is expected<T, E>. It's basically like a variant which can either have the desired value or an "error code" (T can be void if you just want to check to see if a process succeeded).
Of course, you could use an actual variant if you have access to such an implementation. But expected has a nicer interface that's designed for this scenario. And unlike std::variant from C++17, the proposed expected cannot be valueless_by_exception, since E is required to be a nothrow-moveable type (not exactly a high bar for most error codes).
I have a ResourceManager which takes in classes of type Resource. Resource is a parent class of other classes such as ShaderProgram, Texture, Mesh and even Camera who are completely unrelated to one another.
Suffice it to say, the ResourceManager works. But there is one thing that is very tedious and annoying, and that's when I retrieve the objects from the ResourceManager. Here is the problem:
In order to get an object from ResourceManager you call either of these functions:
static Resource* get(int id);
static Resource* get(const std::string &name);
The first function checks one std::unordered_map by an integer id; whereas the second function checks another std::unordered_map by the name that is manually given by the client. I have two versions of these functions for flexibility sakes because there are times where we don't care what the object contained within ResourceManager is (like Mesh) and there are times where we do care about what it is (like Camera or ShaderProgram) because we may want to retrieve the said objects by name rather than id.
Either way, both functions return a pointer to a Resource. When you call the function, it's as easy as something like:
rm::get("skyboxShader");
Where rm is just a typedef of ResourceManager since the class is static (all members/functions are static). The problem though is that the rm::get(..) function returns a Resource*, and not the child class that was added to the ResourceManager to begin with. So, in order to solve this problem I have to do a manual type conversion so that I can get ShaderProgram* instead of Resource*. I do it like this:
auto s = static_cast<ShaderProgram*>(rm::get(name));
So, everytime I want to access a Resource I have to insert the type I want to actually get into the static_cast. This is problematic insofar that everytime someone needs to access a Resource they have to type convert it. So, naturally I created a function, and being that ShaderProgram is the subject here, thus:
ShaderProgram* Renderer::program(const std::string &name)
{
auto s = static_cast<ShaderProgram*>(rm::get(name));
return s;
}
This function is static, and ResourceManager is a static class so the two go well hand-in-hand. This is a nice helper function and it works effectively and my program renders the result just fine. The problem is what I have to do when I'm dealing with other Resources; that means for every Resource that exists, there has to be a type-conversion function to accommodate it. Now THAT is annoying. Isn't there a way I can write a generic type-conversion function something like this?
auto Renderer::getResource(classTypeYouWant T, const std::string &name)
{
auto s = static_cast<T*>(rm::get(name));
return s;
}
Here, the auto keyword causes the function to derive which type it's supposed to be dealing with and return the result accordingly. My first guess is that I might have to use templates; but the problem with templates is that I can't limit which types get inserted into the function, and I really REALLY don't want floating-point id numbers, char ids, let alone custom-defined ids. It's either string (might change to const char* tbh) or ints or else.
How can I create a generic conversion function like the one described above?
Have you looked at using dynamic_cast? If the conversion fails with dynamic_cast the the pointer will be set to nullptr. So you could either write overloads for each type or you could write a template function where you pass the the type you want to convert to as well as the string or id and if the conversion succeeds or fails return true or false.
template<typename T>
bool Renderer::getResource(T*& type, const std::string &name)
{
type = dynamic_cast<decltype(std::remove_reference<decltype(T)>::type)>(rm::get(name));
if (type == nullptr)
return false;
return true;
}
OK, I did not like the idea of a typeless storage, but maybe you find that basic program as a start point. There are a lot of things which must be beautified, but some work must remain :-)
Again: It is a design failure to solve something in that way!
In addition to your example code this solution provides a minimum of safety while checking for the stored type while recall the element. But this solution needs rtti an this is not available on all platforms.
#include <map>
#include <iostream>
#include <typeinfo>
class ResourcePointerStorage
{
private:
std::map< const std::string, std::pair<void*, const std::type_info*>> storage;
public:
bool Get(const std::string& id, std::pair<void*, const std::type_info*>& ptr )
{
auto it= storage.find( id );
if ( it==storage.end() ) return false;
ptr= it->second;
return true;
}
bool Put( const std::string& id, void* ptr, const std::type_info* ti)
{
storage[id]=make_pair(ptr, ti);
}
};
template < typename T>
bool Get(ResourcePointerStorage& rm, const std::string& id, T** ptr)
{
std::pair<void*, const std::type_info*> p;
if ( rm.Get( id,p ))
{
if ( *p.second != typeid(T)) { return false; }
*ptr= static_cast<T*>(p.first);
return true;
}
else
{
return 0;
}
}
template < typename T>
void Put( ResourcePointerStorage& rm, const std::string& id, T *ptr)
{
rm.Put( id, ptr, &typeid(T) );
}
class Car
{
private:
int i;
public:
Car(int _i):i(_i){}
void Print() { std::cout << "A car " << i << std::endl; }
};
class Animal
{
private:
double d;
public:
Animal( double _d):d(_d) {}
void Show() { std::cout << "An animal " << d << std::endl; }
};
int main()
{
ResourcePointerStorage store;
Put( store, "A1", new Animal(1.1) );
Put( store, "A2", new Animal(2.2) );
Put( store, "C1", new Car(3) );
Animal *an;
Car *car;
if ( Get(store, "A1", &an)) { an->Show(); } else { std::cout << "Error" << std::endl; }
if ( Get(store, "A2", &an)) { an->Show(); } else { std::cout << "Error" << std::endl; }
if ( Get(store, "C1", &car)) { car->Print(); } else { std::cout << "Error" << std::endl; }
// not stored object
if ( Get(store, "XX", &an)) { } else { std::cout << "Expected false condition" << std::endl; }
// false type
if ( Get(store, "A1", &car)) { } else { std::cout << "Expected false condition" << std::endl; }
};
I've found the solution to my question. I created a macro:
#define convert(type, func) dynamic_cast<type>(func)
Extremely generic and code-neutral which allows types to be dynamic_casted from the return type of the function. It also allows for doing checks:
if (!convert(ShaderProgram*, rm::get("skyboxShader")))
cerr << "Conversion unsuccessful!" << endl;
else cout << "Conversion successful!" << endl;
I hope my solution will help people who search for questions similar of this kind. Thanks all!
I have an enum class with two values, and I want to create a method which receives a value
and returns the other one. I also want to maintain type safety(that's why I use enum class instead of enums).
http://www.cplusplus.com/doc/tutorial/other_data_types/ doesn't mention anything about methods
However, I was under the impression that any type of class can have methods.
No, they can't.
I can understand that the enum class part for strongly typed enums in C++11 might seem to imply that your enum has class traits too, but it's not the case. My educated guess is that the choice of the keywords was inspired by the pattern we used before C++11 to get scoped enums:
class Foo {
public:
enum {BAR, BAZ};
};
However, that's just syntax. Again, enum class is not a class.
While the answer that "you can't" is technically correct, I believe you may be able to achieve the behavior you're looking for using the following idea:
I imagine that you want to write something like:
Fruit f = Fruit::Strawberry;
f.IsYellow();
And you were hoping that the code looks something like this:
enum class Fruit : uint8_t
{
Apple,
Pear,
Banana,
Strawberry,
bool IsYellow() { return this == Banana; }
};
But of course, it doesn't work, because enums can't have methods (and 'this' doesn't mean anything in the above context)
However, if you use the idea of a normal class containing a non-class enum and a single member variable that contains a value of that type, you can get extremely close to the syntax/behavior/type safety that you want. i.e.:
class Fruit
{
public:
enum Value : uint8_t
{
Apple,
Pear,
Banana,
Strawberry
};
Fruit() = default;
constexpr Fruit(Value aFruit) : value(aFruit) { }
#if Enable switch(fruit) use case:
// Allow switch and comparisons.
constexpr operator Value() const { return value; }
// Prevent usage: if(fruit)
explicit operator bool() const = delete;
#else
constexpr bool operator==(Fruit a) const { return value == a.value; }
constexpr bool operator!=(Fruit a) const { return value != a.value; }
#endif
constexpr bool IsYellow() const { return value == Banana; }
private:
Value value;
};
Now you can write:
Fruit f = Fruit::Strawberry;
f.IsYellow();
And the compiler will prevent things like:
Fruit f = 1; // Compile time error.
You could easily add methods such that:
Fruit f("Apple");
and
f.ToString();
can be supported.
Concentrating on the description of the question instead of the title a possible answer is
struct LowLevelMouseEvent {
enum Enum {
mouse_event_uninitialized = -2000000000, // generate crash if try to use it uninitialized.
mouse_event_unknown = 0,
mouse_event_unimplemented,
mouse_event_unnecessary,
mouse_event_move,
mouse_event_left_down,
mouse_event_left_up,
mouse_event_right_down,
mouse_event_right_up,
mouse_event_middle_down,
mouse_event_middle_up,
mouse_event_wheel
};
static const char* ToStr (const type::LowLevelMouseEvent::Enum& event)
{
switch (event) {
case mouse_event_unknown: return "unknown";
case mouse_event_unimplemented: return "unimplemented";
case mouse_event_unnecessary: return "unnecessary";
case mouse_event_move: return "move";
case mouse_event_left_down: return "left down";
case mouse_event_left_up: return "left up";
case mouse_event_right_down: return "right down";
case mouse_event_right_up: return "right up";
case mouse_event_middle_down: return "middle down";
case mouse_event_middle_up: return "middle up";
case mouse_event_wheel: return "wheel";
default:
Assert (false);
break;
}
return "";
}
};
There is a pretty compatible ability(§) to refactor an enum into a class without having to rewrite your code, which means that effectively you can do what you were asking to do without too much editing.
(§) as ElementW points out in a comment, type_traits dependent code will not work, so e.g. one cannot use auto, etc. There may be some way of handling such stuff, but in the end one is converting an enum into a class, and it is always a mistake to subvert C++
the enum struct and enum class specifications are about scoping so not part of this.
Your original enum is e.g. 'pet' (this is as an example only!).
enum pet {
fish, cat, dog, bird, rabbit, other
};
(1) You modify that to eg petEnum (so as to hide it from your existing code).
enum petEnum {
fish, cat, dog, bird, rabbit, other
};
(2) You add a new class declaration below it (named with the original enum)
class pet {
private:
petEnum value;
pet() {}
public:
pet(const petEnum& v) : value{v} {} //not explicit here.
operator petEnum() const { return value; }
pet& operator=(petEnum v) { value = v; return *this;}
bool operator==(const petEnum v) const { return value == v; }
bool operator!=(const petEnum v) const { return value != v; }
// operator std::string() const;
};
(3) You can now add whatever class methods you like to your pet class.
eg. a string operator
pet::operator std::string() const {
switch (value) {
case fish: return "fish";
case cat: return "cat";
case dog: return "dog";
case bird: return "bird";
case rabbit: return "rabbit";
case other: return "Wow. How exotic of you!";
}
}
Now you can use eg std::cout...
int main() {
pet myPet = rabbit;
if(myPet != fish) {
cout << "No splashing! ";
}
std::cout << "I have a " << std::string(myPet) << std::endl;
return 0;
}
As mentioned in the other answer, no. Even enum class isn't a class.
Usually the need to have methods for an enum results from the reason that it's not a regular (just incrementing) enum, but kind of bitwise definition of values to be masked or need other bit-arithmetic operations:
enum class Flags : unsigned char {
Flag1 = 0x01 , // Bit #0
Flag2 = 0x02 , // Bit #1
Flag3 = 0x04 , // Bit #3
// aso ...
}
// Sets both lower bits
unsigned char flags = (unsigned char)(Flags::Flag1 | Flags::Flag2);
// Set Flag3
flags |= Flags::Flag3;
// Reset Flag2
flags &= ~Flags::Flag2;
Obviously one thinks of encapsulating the necessary operations to re-/set single/group of bits, by e.g. bit mask value or even bit index driven operations would be useful for manipulation of such a set of 'flags'.
The c++11 struct/class specification just supports better scoping of enum values for access. No more, no less!
Ways to get out of the restriction you cannot declare methods for enum (classes) are , either to use a std::bitset (wrapper class), or a bitfield union.
unions, and such bitfield unions can have methods (see here for the restrictions!).
I have a sample, how to convert bit mask values (as shown above) to their corresponding bit indices, that can be used along a std::bitset here: BitIndexConverter.hpp
I've found this pretty useful for enhancing readability of some 'flag' decison based algorithms.
It may not fulfill all your needs, but with non-member operators you can still have a lot of fun. For example:
#include <iostream>
enum class security_level
{
none, low, medium, high
};
static bool operator!(security_level s) { return s == security_level::none; }
static security_level& operator++(security_level& s)
{
switch(s)
{
case security_level::none: s = security_level::low; break;
case security_level::low: s = security_level::medium; break;
case security_level::medium: s = security_level::high; break;
case security_level::high: break;
}
return s;
}
static std::ostream & operator<<(std::ostream &o, security_level s)
{
switch(s)
{
case security_level::none: return o << "none";
case security_level::low: return o << "low";
case security_level::medium: return o << "medium";
case security_level::high: return o << "high";
}
}
This allows code like
security_level l = security_level::none;
if(!!l) { std::cout << "has a security level: " << l << std::endl; } // not reached
++++l;
if(!!l) { std::cout << "has a security level: " << l << std::endl; } // reached: "medium"
Based on jtlim's answer
Idea (Solution)
enum ErrorType: int {
noConnection,
noMemory
};
class Error {
public:
Error() = default;
constexpr Error(ErrorType type) : type(type) { }
operator ErrorType() const { return type; }
constexpr bool operator == (Error error) const { return type == error.type; }
constexpr bool operator != (Error error) const { return type != error.type; }
constexpr bool operator == (ErrorType errorType) const { return type == errorType; }
constexpr bool operator != (ErrorType errorType) const { return type != errorType; }
String description() {
switch (type) {
case noConnection: return "no connection";
case noMemory: return "no memory";
default: return "undefined error";
}
}
private:
ErrorType type;
};
Usage
Error err = Error(noConnection);
err = noMemory;
print("1 " + err.description());
switch (err) {
case noConnection:
print("2 bad connection");
break;
case noMemory:
print("2 disk is full");
break;
default:
print("2 oops");
break;
}
if (err == noMemory) { print("3 Errors match"); }
if (err != noConnection) { print("4 Errors don't match"); }
Yes, they can, but you need to make a wrapper class, for example:
#include <iostream>
using namespace std;
class Selection {
public:
enum SelectionEnum {
yes,
maybe,
iDontKnow,
canYouRepeatTheQuestion
};
Selection(SelectionEnum selection){value=selection;};
string toString() {
string selectionToString[4]={
"Yes",
"Maybe",
"I don't know",
"Can you repeat the question?"
};
return selectionToString[value];
};
private:
SelectionEnum value;
};
int main(){
Selection s=Selection(Selection::yes);
cout<<s.toString()<<endl;
return 0;
}
is there any way to declare a variety number of member variables from different user-data type generically using template operator?
consider this code:
class a {
int member;
void ProcessMemberVariable ();
};
class b {
char member;
void ProcessMemberVariable ();
};
... // arbitrary number of such classes
class test {
template <typename T>
void declare (T a ) {
// each time this member function is called a new member variable of the
// user data type T shall be declared in the instance of the class test??
}
};
int ()
{
test Test;
Test.template declare<a>(a A);
Test.template declare<b>(b B);
...
}
Imagine You want to implement an interface which is apple to set any kind of user defined data type. Since I know the identifier of user-defined data type only when I declare an instance of class "test" and call its member function...
I appreciate each suggestion..
What you are describing sounds like dynamically adding members to an object, and this isn't possible in C++. There are various ways to get a similar effect in certain situations, but you would need to describe a situation where you thought this would be useful.
As stated there is no way to dynamically add member variables at runtime.
However, if you know the list of types that you may want to add at runtime you could achieve this behaviour using boost::variant. Below is a trivial example (
#include <iostream>
#include <string>
#include <map>
#include <boost/variant.hpp>
using namespace std;
class Test
{
public:
typedef boost::variant< long, double, string > VariantType;
template< typename T >
void Declare( std::string name, T val )
{
VariantType newVal = val;
varMap.insert( std::make_pair( std::move( name ), std::move( val ) ) );
}
VariantType Get( const std::string& name )
{
return varMap[ name ];
}
template< typename T >
T GetValue( const std::string& name )
{
return boost::get<T>( varMap[name] );
}
private:
std::map< string, VariantType > varMap;
};
int main()
{
Test t{};
t.Declare( "Var1", 10l );
t.Declare( "pi", 3.14159);
t.Declare( "AString", "SomeName" );
cout << "t.get( Var1 ) " << t.GetValue<long>( "Var1" ) << "\n";
cout << "t.get( pi ) " << t.GetValue<double>( "pi" ) << "\n";
cout << "t.get( AString ) " << t.GetValue<string>( "AString" ) << "\n";
return 0;
}
See: http://www.boost.org/doc/libs/1_49_0/doc/html/variant.html for details on how to use boost::variant.