I tried to make a static assertion on a template parameter, to check/enforce the Type
to be copy constructible. However the static assertion fails. I fail to understand why, and cannot find any documentation why would it fail on static evaluation.
The instantiated class is copy constructible, however it uses what I believe is called curiously recurring template parameter pattern.
Below is the whole test code:
#include <iostream>
#include <type_traits>
using namespace std;
template<typename Type>
class FunContainer {
// static_assert(is_copy_constructible<Type>::value, "Type must be copy constructible!"); // <- This fails.
// bool copyable = is_copy_constructible<Type>::value // <- will make the second assert fail
protected:
int container_stuff = 0;
public:
int get_container_stuff() {return container_stuff;};
void set_container_stuff(int stuff) {container_stuff = stuff;};
bool is_copyable() {return is_copy_constructible<Type>::value;};
};
class Fun : public FunContainer<Fun> {
public:
std::string str = "Tastic";
Fun() = default;
Fun(const Fun& other_fun) : FunContainer<Fun>(other_fun) {
copy_internals(other_fun);
};
Fun& operator=(const Fun& other_fun){
FunContainer<Fun>::operator=(other_fun);
copy_internals(other_fun);
return *this;
};
private:
void copy_internals(const Fun& other_fun) {str = other_fun.str;};
};
static_assert(is_copy_constructible<Fun>::value, "Type must be copy constructible!"); // <- the 2nd assert
int main() {
Fun fun;
fun.set_container_stuff(10);
fun.str = "test";
Fun tastic(fun);
cout << tastic.get_container_stuff() << '\n';
cout << tastic.str << '\n';
cout << tastic.is_copyable() << '\n';
return 0;
}
Result is as expected:
10
test
1
Which means the 2nd assert passed. So it seems that the Fun
is not CopyConstructible inside the FunContainer
. However, the is_copyable
says it is.
I also tried to change is_copyable()
method to use a bool
initialized in-class It makes the second assertion fail. When obstructing assertions are removed the value is of copyable
gets set to 0;
It seems that only evaluation failing is static copmile-time within the base class.
Q1 Why is compile-time check false
and "run-time" true
? Does it fail because the class (Fun
) is not fully instantiated/defined at the check time?
Q2 Is this expected? (That the static evaluation of is_copy_constructible gives result than different "run-time" one).
Q3 Is there a way to make a compile-time assertion that would check if class is CopyConstructible with such a design?
Tested on clang 3.2-11, gcc 4.8.2 and ideone default c++11 compiler.