我尝试在模板参数上进行静态断言,以检查/强制Type
是可复制构造的。但静态断言失败了。我无法理解为什么,也找不到任何文档,为什么它会在静态评估中失败。
实例化的类是可复制构造的,但是它使用我认为被称为奇怪的重复模板参数模式。
以下是整个测试代码:
#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;
}
结果符合预期:
10
test
1
这意味着第二个断言通过了。所以似乎Fun
不是FunContainer
内的CopyConstructible。但是,is_copyable
表示确实如此。
我还尝试将is_copyable()
方法更改为使用bool
初始化的类中它使第二个断言失败。当阻止断言被删除时,copyable
的值被设置为0;
似乎只有评估失败才是基类中的静态copmile-time。
Q1 为什么编译时检查false
和“运行时”true
?是否因为在检查时没有完全实例化/定义类(Fun
)而失败?
Q2 这是预期的吗? (is_copy_constructible的静态评估给出的结果不同于“运行时”)。
Q3 有没有办法制作一个编译时断言来检查类是否是具有这种设计的CopyConstructible?
在clang 3.2-11,gcc 4.8.2和ideone default c ++ 11编译器上测试过。
答案 0 :(得分:6)
Q1 为什么编译时检查错误,“运行时”为真?是否因为在检查时没有完全实例化/定义类(Fun)而失败?
是。 FunContainer<Fun>
在Fun
定义之前被实例化,当您将其用作Fun
的基类时。
Q2 这是预期的吗?
是
Q3 有没有办法进行编译时断言,检查类是否具有类似设计的CopyConstructible?
将静态断言移动到稍后实例化的某个位置。内部FunContainer
的构造函数对我来说似乎是一个不错的选择。