Actually, I'm not sure if using the operator< or any other comparison operator other than operator== is even valid, but I've not seen anything to suggest otherwise. So assuming that is valid, is there a way of determining if an enum is valid using SFINAE?
While
std::is_signed<std::underlying_type<EnumType>::type>::value
is the portable solution, however it is not yet available in all commonly used compilers. From the question it's not clear whether you are also asking about enum class, or just about enum, but maybe this work-around will do the job:
#include <iostream>
#include <iomanip>
enum S : int {};
enum U : unsigned {};
enum class SC : int {};
enum class UC : unsigned {};
template< typename E >
struct is_enum_signed {
static const bool value = E(-1) < E(0);
};
int main()
{
std::cout << std::boolalpha
<< is_enum_signed<S>::value << std::endl
<< is_enum_signed<U>::value << std::endl
<< is_enum_signed<SC>::value << std::endl
<< is_enum_signed<UC>::value << std::endl;
}
Disclaimer: I haven't checked whether or not it is standard-conforming, I'm just trying to offer an alternative of which you need to verify applicability and correctness for your environment...
Related
C++ has is_base_of<Base,Derived>. However, this also includes “grandparent” types.
Is there a way to get have is_child_of<Parent,Child> functionality? The purpose is to use types as sentinel 'interface' markers in an SFINAE context, without being affected by sentinels that may or may not be added to parent types.
That is, the following output is expected to be "true, false". (The output with is_base_of is "true, true".)
#include <iostream>
#include <type_traits>
class A {};
class B : A {};
class C : B {};
int main()
{
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_child_of<A, B>::value << '\n';
std::cout << "a2c: " << std::is_child_of<A, C>::value << '\n';
}
C++ doesn't have reflection, child's storage contain's parent's storage and it's hard to draw a line between one subobject and another. Some metaprogramming must be dome, mimicking libraries similar to Qt or MFC\WFC
#include <iostream>
#include <type_traits>
#define DECLARE_CLASS(Name, ParentName) using Parent = ParentName;
#define PARENT_CLASS(Name) Name::Parent
class LibBase {
public:
DECLARE_CLASS(LibBase, void)
};
class A : public LibBase {
public:
DECLARE_CLASS(A, LibBase)
};
class B : public A {
public:
DECLARE_CLASS(B, A)
};
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_same<PARENT_CLASS(B), A>::value << std::endl;
std::cout << std::is_same<PARENT_CLASS(B), LibBase>::value << std::endl;
}
Clearly this simple approach have pitfall that we don't get an error if class is not defined using our macro., and it is static only,
First issue can worked around by creating a "trait" nested class by declaration, which got name based on class name passed to DECLARE_OBJECT. This would make result of PARENT_CLASS(Name) unique, e.g.
#define DECLARE_CLASS(Name, ParentName) struct TraitsOf##Name { \
using Parent = ParentName; \
};
#define PARENT_CLASS(Name) Name::TraitsOf##Name::Parent
Second issue can be worked around by creating own RTTI function within macro-definition
Sadly form is_child_of<LibBase, A>::value is unattainable with this because macro substitution happens before template substitution. Perhaps some static registering approach can be used to give classes unique traits in wait how BOOST_TYPEOF does but getting rid of macrodefinitions in user code would be nigh-impossible.
i have this piece of code (http://coliru.stacked-crooked.com/a/ee05a00fc8ab5057):
#include <type_traits>
struct unregistered;
unregistered register_type(...);
template<class T>
constexpr bool is_registered = !std::is_same_v<unregistered, decltype(register_type(std::declval<T>()))>;
template<class T>
struct test_registration
{
static_assert(is_registered<T>, "Type is not registered!");
};
struct foo{};
struct bar{};
void register_type(int);
void register_type(char);
void register_type(void*);
void register_type(foo);
void register_type(foo*);
#include <boost/core/demangle.hpp>
#include <iostream>
int main()
{
std::cout << boost::core::demangle(typeid(test_registration<foo>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<foo*>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<int>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<char>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<void*>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<long>).name()) << "\n";
std::cout << boost::core::demangle(typeid(test_registration<bar>).name()) << "\n";
return 0;
}
The compiler generates errors for the calls using int, char, void*, long and bar.
I expect the errors for long and bar.
What I do not understand is:
Why are int, char, and foo treated differently?
Why are void*, and foo* treated differently? (both are ptrs)
I assume the reason has to do with foo beeing class type and int and char beeing plain types.
I would like to know the reason. Is it a compiler bug or is there some passage in the standard explaining this behaviour?
What I am asking is not how I can fix this problem (see link to coliru for a fix).
What I want to know is why it is behaving like this.
I've been recently getting into template wizardry and in particular CRTP. I know that templates are used to make the compiler generate code for us so I was wondering if it were possible to make a template "decide" which parts of a function we would like it to include for a particular class. For example if I have the following code:
crtp.h
#include <iostream>
using std::endl;
using std::cout;
template<class T>
class A {
public:
void func() {
constexpr unsigned short mask = T::GetMask();
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
}
};
class B : public A<B> {
friend class A<B>;
protected:
static constexpr unsigned short GetMask() { return 0x0001; }
};
class C : public A<C> {
friend class A<C>;
protected:
static constexpr unsigned short GetMask() { return 0x0009; }
};
main.cpp
#include "ctrp.h"
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
using std::getchar;
using std::endl;
int main() {
B b;
C c;
cout << "B:" << endl;
b.func();
cout << endl << "C:" << endl;
c.func();
getchar();
}
Which when executed produces:
B:
Mask 1
C:
Mask 1
Mask 2
This works great, does exactly what I want it to. The problem is from my standpoint the if statements should be unnecessary. As I am dealing with constant expressions the compiler should have everything it needs to simply skip the branching and know to execute the first part for class B and both parts for class C.
I would like to cash in on this and specifically tell the compiler to remove the sections that are unnecessary for the particular class to avoid unnecessary branching at runtime. Unfortunately I have no idea how to do this, any ideas? Thanks in advance
Edit
In response to some of the awesome suggestions C++17's constexpr if expression is a near perfect solution that I had no idea existed, but am unfortunately unable to use. I am limited to using C++14.
If you care about performance, the compiler will very likely optimize out all "dead" branches and even the if condition, if it can evaluate it during compile time.
What is worse, all the branches need to be well formed until C++17 constexpr if. In this case, you can "outsource" the functionality to special (static member) functions and use specialization to invoke the right one. See #R Sahu's answer for the example.
Emulating if/else at compile time using template metaprogramming does not work that way. You have to imagine if/else using a different mindset.
Instead of
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
you'll have to use something along the lines of:
function1_selector<mask & 1>::dostuff();
function2_selector<mask & 1 << 3 >::dostuff();
where
template <bool> struct function1_selector
{
static void dostuff() { /* Do nothing */ }
};
template <> struct function1_selector<true> // Specialize for true
{
static void dostuff() { /* Do something useful */ }
};
Add code for function2_selector similarly.
When attempting to access a tuple's value via a scoped and typed enum, I get an error saying there is no matching type for std::get.
enum class User: std::size_t {
FirstName = 1,
LastName = 2,
};
std::tuple<std::string, std::string> user("Bobby", "Bean");
// Error
std::cout << std::get<User::FirstName>(user) << std::endl;
Given that std::get expects type std::size_t and the underlying type of the enum is also std::size_t, why does this fail?
I'm aware that I can cast the value of the enum, but I'm not sure why that would be necessary given that both underlying types are the same. With an unscoped enum, this works just fine.
Enum classes really aren't integers on the surface. Just like a struct containing just an int is not an int.
The C++ standard way back to the integer representation is this:
using UserUndT = std::underlying_type<User>::type;
std::cout <<
std::get<static_cast<UserUndT>(User::FirstName)>(user) << std::endl;
Also, check out this question: Using enable_if and underlying_type in function signature in VS2012
An alternative worth considering: (C++14)
#include <iostream>
#include <tuple>
struct FirstName {
std::string val;
};
struct LastName {
std::string val;
};
using FullName = std::tuple<FirstName,LastName>;
int main() {
auto user = FullName({"John"},{"Deer"});
std::cout << std::get<FirstName>(user).val << std::endl;
std::cout << std::get<LastName>(user).val << std::endl;
}
to get what you want you can do:
namespace User{enum User:size_t{FirstName,LastName};};
then you will have the bare typed enum again.
The namespace solution works but not inside a function or class. An alternative is as follows:
#include <iostream>
#include <tuple>
#include <vector>
#include <string>
using namespace std;
int main()
{
struct Test{enum size_t{first, second, third};};
vector<tuple<int, string, bool>> mt;
mt.emplace_back(make_tuple(10, "hello", true));
cout << get<Test::first>(mt[0]) << ' ' << get<Test::second>(mt[0]) << ' ' << get<Test::third>(mt[0]) << endl;
return 0;
}
I am reading sometimes about type determination in runtime based on typeid, I try the following code
#include <iostream>
#include <vector>
#include <typeinfo>
typedef std::vector<int> Vector;
template <class T> void foo(T &v)
{
cout << typeid(Vector::value_type).name() << endl; // this is ok
cout << typeid(T::value_type).name() << endl; // this doesn't compile
}
void main(void)
{Vector v;
foo(v);
}
The above code compiles only when we put in the specific type into typeid, but it doesn't work if I use template T instead. So if I have a container v, how can I determine the value type in runtime? Thanks.
You need to use typename:
cout << typeid(typename T::value_type).name() << endl;
This has nothing to do with typeid. This is a general issue whenever you use a member of a class where the specific class you use depends on a template parameter. By default, the compiler assumes that all members of some unknown class T are not types. You have to explicitly tell it otherwise.