H i and thank you for all the replies, btw fcantoro I know my original post doesn't compile which is why I included the coments to demonstrate my intent :)
Ok, in the example it is not possible to have Foo declared as a member of a general class as it requires it to be declared as constexpr in order to call the constexpr constructor and in fact it is not possible at all. i.e you can't do this....
1 2 3 4 5 6 7
|
class SomeNonTemplateClass
{
...
private:
Foo foo // not possible as a constexpr
};
|
Now you say that you don't really need a initializable constexpr member, but consider the following class...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
template<typename T> // some common type known at the time of declaration
struct Foo
{
Foo() = default;
template<class ctype>
Foo(ctype type) : cexpr(sizeof(type)) {}
Foo(const Foo&& foo) : cexpr(foo.cexpr)
{
}
template<class type>
static Foo<T> Get(type ty)
{
return std::forward<Foo<T>>(Foo<T>(type))
}
//....
void CallSomeCompileTimeMethod(void)
{
SomeSpecializedClass<cexpr>::SomeMethod // static in this example but not necessarily so.
}
constexpr std::size_t cexpr;
};// end Foo
|
Now inside a general class....
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
class SomeGeneralClass
{
....
SomeMemberMethod(void)
{
foo = Foo<KnownType>::Get(Only now do we know this type);
foo.CallSomeCompileTimeMethod();
}
private:
Foo<KnownType> foo // default constructor called.
}
|
So as you can see from above if this were possible class Foo could be a generic dispatching class for any number of methods, in this case based on an objects size. In release mode the compiler would ( in the absence of any classes using virtual inheritance ) optimize away class Foo entirely and it would implicitly inline the method called by CallSomeCompileTimeMethod.
Yes, I know I have an uninitialized constexpr in class Foo, but this in and of itself is not a big issue, remember this happens at complile time so it could therefore follow SFINAE. Any code paths using an uninitialized constexpr cause the the path to be removed, or failing that a compile time error seeing as the sizeof operator is one of the very first to be evaluated; it has to be this way so the stack can be properly grown and unwound.
I apologise in advance for any mistakes in my examples, it's written from memory and only there to describe my intention.