Boost lock free queue asserts 用于简单的赋值和析构函数
Boost lock free queue asserts for trivial assignment and destructor
尝试将 "Event" 插入 boost lock free 队列时,我收到:
错误:静态断言失败:(boost::has_trivial_destructor::value) 和静态断言失败:(boost::has_trivial_assign::value)。我知道容器的要求是:
T 必须有一个复制构造函数
T 必须有一个平凡的赋值运算符
T 必须有一个平凡的析构函数
我不确定为什么我的活动 class 不符合这些要求。
我读过这个 question/answer:/boost/lockfree/queue.hpp: error: static assertion failed: (boost::has_trivial_destructor<T>::value)。我不明白为什么我的 class 不满足要求。
struct Event
{
typedef uint8_t Event_Type;
//event bitmask..
enum : uint8_t
{
SS = 1,
TS = 2
};
static constexpr uint8_t BOTH = SS | TS;
Event(): _time {}
,_data1 {}
,_eventType {}
,_data2 {}
{}
Event(const Event& event_)
{
_id = event_._id;
_time = event_._time;
_data1 = event_.data1;
_eventType = event_._eventType;
_data2 = event_.data2;
}
template<Event_Type type, typename... Args >
void update(Args...args)
{
_eventType |= type;
apply(std::forward<Args>(args)...);
}
void apply(int32_t d)
{
data1 = d;
}
void apply(bool b)
{
data2= b;
}
template<typename Event, typename... Args>
void apply(Event event, Args... args)
{
apply(event);
apply(args...);
}
std::string _id;
int64_t _time;
int32_t _data1;
Event_Type _eventType;
bool _data2;
};
boost::lockfree::queue<Event, boost::lockfree::fixed_sized<false>> q;
Event e;
e._id="test";
q.push(event);
/boost/1.57.0/include/boost/static_assert.hpp:78:41:错误:静态断言失败:(boost::has_trivial_destructor::value)
# 定义 BOOST_STATIC_ASSERT( ... ) static_assert(VA_ARGS, #VA_ARGS )
boost/1.57.0/include/boost/static_assert.hpp:78:41:错误:静态断言失败:(boost::has_trivial_assign::value)
# 定义 BOOST_STATIC_ASSERT( ... ) static_assert(VA_ARGS, #VA_ARGS )
您的 Event
class 有一个 std::string
类型的成员,它有一个 non-trivial 赋值运算符和一个 non-trivial 析构函数。这些阻止了 auto-generated 赋值运算符和 Event
本身的析构函数变得微不足道。 (请记住,"trivial" 不仅仅意味着 "defaulted"。它还意味着默认行为不必做任何有趣的事情。一个简单的赋值只是复制位;一个简单的析构函数是一个 no-op.)
std::string
没有平凡的复制赋值运算符或平凡的析构函数。因为它没有,而且它是您 class 的成员,这意味着您的 class 也没有。如果你想让它变得微不足道,你必须删除字符串成员。
除了其他两个答案指出 std::string
数据成员阻止构造函数变得平凡之外,Event()
构造函数本身也必须是平凡的。这意味着它必须由编译器生成,而不是由用户实现。它可以通过完全删除构造函数或将其标记为显式默认 (Event() = default;
) 来实现。拷贝构造函数和赋值运算符也是如此。
一般来说,列出了普通默认构造函数的要求 here。
尝试将 "Event" 插入 boost lock free 队列时,我收到: 错误:静态断言失败:(boost::has_trivial_destructor::value) 和静态断言失败:(boost::has_trivial_assign::value)。我知道容器的要求是: T 必须有一个复制构造函数 T 必须有一个平凡的赋值运算符 T 必须有一个平凡的析构函数 我不确定为什么我的活动 class 不符合这些要求。
我读过这个 question/answer:/boost/lockfree/queue.hpp: error: static assertion failed: (boost::has_trivial_destructor<T>::value)。我不明白为什么我的 class 不满足要求。
struct Event
{
typedef uint8_t Event_Type;
//event bitmask..
enum : uint8_t
{
SS = 1,
TS = 2
};
static constexpr uint8_t BOTH = SS | TS;
Event(): _time {}
,_data1 {}
,_eventType {}
,_data2 {}
{}
Event(const Event& event_)
{
_id = event_._id;
_time = event_._time;
_data1 = event_.data1;
_eventType = event_._eventType;
_data2 = event_.data2;
}
template<Event_Type type, typename... Args >
void update(Args...args)
{
_eventType |= type;
apply(std::forward<Args>(args)...);
}
void apply(int32_t d)
{
data1 = d;
}
void apply(bool b)
{
data2= b;
}
template<typename Event, typename... Args>
void apply(Event event, Args... args)
{
apply(event);
apply(args...);
}
std::string _id;
int64_t _time;
int32_t _data1;
Event_Type _eventType;
bool _data2;
};
boost::lockfree::queue<Event, boost::lockfree::fixed_sized<false>> q;
Event e;
e._id="test";
q.push(event);
/boost/1.57.0/include/boost/static_assert.hpp:78:41:错误:静态断言失败:(boost::has_trivial_destructor::value) # 定义 BOOST_STATIC_ASSERT( ... ) static_assert(VA_ARGS, #VA_ARGS )
boost/1.57.0/include/boost/static_assert.hpp:78:41:错误:静态断言失败:(boost::has_trivial_assign::value) # 定义 BOOST_STATIC_ASSERT( ... ) static_assert(VA_ARGS, #VA_ARGS )
您的 Event
class 有一个 std::string
类型的成员,它有一个 non-trivial 赋值运算符和一个 non-trivial 析构函数。这些阻止了 auto-generated 赋值运算符和 Event
本身的析构函数变得微不足道。 (请记住,"trivial" 不仅仅意味着 "defaulted"。它还意味着默认行为不必做任何有趣的事情。一个简单的赋值只是复制位;一个简单的析构函数是一个 no-op.)
std::string
没有平凡的复制赋值运算符或平凡的析构函数。因为它没有,而且它是您 class 的成员,这意味着您的 class 也没有。如果你想让它变得微不足道,你必须删除字符串成员。
除了其他两个答案指出 std::string
数据成员阻止构造函数变得平凡之外,Event()
构造函数本身也必须是平凡的。这意味着它必须由编译器生成,而不是由用户实现。它可以通过完全删除构造函数或将其标记为显式默认 (Event() = default;
) 来实现。拷贝构造函数和赋值运算符也是如此。
一般来说,列出了普通默认构造函数的要求 here。