对于多态性,通常的方法是使用std::vector<base*>.但是,我必须自己提供地址,即自己管理内存,无论是使用std::unique_ptr<>还是原始指针.
我想要一个polymorphic_storage<base>接受任何继承类型的类型base.我还希望将类型存储在连续的内存中,以便更快地遍历和缓存相关的问题.
但是,存在一个非常大的问题:在存储级别缺少类型信息时,必须在调整大小时调用正确的移动/复制操作.
功能要求:
我可以用什么机制来实现这个目标?
虽然我提供了答案,但我欢迎任何人发布他们的解决方案.
我有生成lambda的函数,它充当我稍后可以调用的函数的包装器:
template <typename F, typename... FArgs>
auto make_lambda( F&& f, FArgs&&... f_args )
{
return [&] () -> std::result_of_t<F( FArgs... )>
{
return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};
}
Run Code Online (Sandbox Code Playgroud)
我想noexcept在参数f为的时候返回lambda noexcept,所以我的函数返回看起来像这样:
return [&] () noexcept( is_noexcept<decltype( f )>::value )
-> std::result_of_t<F( FArgs... )>
{
return std::forward<F>( f )( std::forward<FArgs>( f_args )... );
};
Run Code Online (Sandbox Code Playgroud)
我的尝试:
#include <type_traits>
void f() {}
void g() noexcept {}
template <typename F, typename... Args>
struct is_noexcept : std::false_type …Run Code Online (Sandbox Code Playgroud) 考虑这两个可能的类定义:
图表A:
struct A
{
A() = delete;
};
Run Code Online (Sandbox Code Playgroud)
图表A':
struct A
{
A() noexcept = delete;
}
Run Code Online (Sandbox Code Playgroud)
声明删除的函数是否有任何意义noexcept?
第一个类将用于私有继承,以确保完全相同的布局.这应该使铸件安全.
#include <iostream>
#include <string>
struct data_base
{
data_base( int i, std::string&& s ) noexcept
: i_{ i }
, s_{ std::move( s ) }
{}
int i_;
std::string s_;
};
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子,我打印int数据成员第一接着std::string对实例数据成员data<true>.
template<bool = true>
struct data : private data_base // inherits
{
data( int i, std::string&& s ) noexcept
: data_base( i, std::move( s ) )
{}
void print()
{
std::cout << "data<true> - " << i_ << s_ << '\n';
}
}; …Run Code Online (Sandbox Code Playgroud) 标准工作草案(n4582,20.6.3,第522页)规定了以下实施建议std::any:
实现应该避免为小的包含对象使用动态分配的内存.[示例:构造的对象仅包含int.-end example]这种小对象优化只应用于is_nothrow_move_constructible_v为真的类型T.
据我所知,std::any可以通过类型擦除/虚函数和动态分配内存轻松实现.
std::any如果在销毁时没有编译时间信息,如何避免动态分配并仍然销毁这些值; 如何设计符合标准建议的解决方案?
如果有人想看到非动态部分的可能实现,我在Code Review上发布了一个:https://codereview.stackexchange.com/questions/128011/an-implementation-of-a-static-any-类型
这里的答案有点太长了.这是基于Kerrek SB对以下评论的建议.
为简单起见,我们将其std::tuple用作我们的类型列表.
在两个类型中交换两种类型的最佳(简洁,最少递归等)方法是std::tuple什么?
通过使用索引来说明功能:
#include <tuple>
int main()
{
using tuple_t = std::tuple<int, void, double>; // int, void, double
using swapped_tuple_t = std::tuple<double, void, int>; // double, void, int
static_assert( std::is_same<swap<0, 2, tuple_t>::type, swapped_tuple_t>::value, "!" );
}
Run Code Online (Sandbox Code Playgroud) 我想做以下事情:
// have a constexpr function
template<class T>
constexpr T square( T const i )
{
return i * i;
}
// transform a std::integer_sequence<> by calling the constexpr function on every integer
template<class Fn, class T, T... values>
static constexpr auto make_type( Fn fn, std::integer_sequence<T, values...> )
{
return std::integer_sequence<T, fn( values )...>{};
}
// so that I can use it like so
using type = decltype( make_type( square, std::integer_sequence<int, 1, 2, 3>{} ) );
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
...\main.cpp | 19 …
该代码在i7-4790处理器(x86-64)上的VC++ 2013(v120)下编译没有问题.
int main()
{
std::atomic<std::unique_ptr<int>> p;
p.store(std::make_unique<int>(5));
}
Run Code Online (Sandbox Code Playgroud)
一旦main()返回,我就崩溃了:
表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)
这是怎么回事?
我希望能够编写generate_tuple_type<int, 3>内部具有类型别名的内容type,std::tuple<int, int, int>在这种情况下.
一些示例用法:
int main()
{
using gen_tuple_t = generate_tuple_type<int, 3>::type;
using hand_tuple_t = std::tuple<int, int, int>;
static_assert( std::is_same<gen_tuple_t, hand_tuple_t>::value, "different types" );
}
Run Code Online (Sandbox Code Playgroud)
我怎么能做到这一点?
使用std::tuple<>我的类型列表,我希望能够有一个模板:
template<std::size_t i_src, std::size_t i_dst, class Tuple>
struct tuple_shift
{
// implementation
};
Run Code Online (Sandbox Code Playgroud)
包含的type别名将返回移位类型列表,以便以下示例编译:
// move type at i_src to i_dst and shift the types
// i_src = 1, i_dst = 3 : right to left shift
using tuple_t = std::tuple<int, char, long, double, float>; // before
using expected_tuple_t = std::tuple<int, long, double, char, float>; // after
using result_tuple_t = tuple_shift<1, 3, tuple_t>::type; // actual result
static_assert( std::is_same<expected_tuple_t, result_tuple_t>::value, "!" );
Run Code Online (Sandbox Code Playgroud)
示例用例:类型列表的稳定排序.
我有一些看起来像这样的代码:
struct mystruct
{
/* lots of members */
};
void mystruct_init( struct mystruct* dst, int const condition )
{
if ( condition )
{
/* initialize members individually a certain way */
}
else
{
/* initialize members individually another way */
}
}
Run Code Online (Sandbox Code Playgroud)
我正在考虑的选项:
在C11中处理这种情况的正确方法是什么?
是在结构定义全局变量还是局部变量之后声明的变量?
struct student {
int id;
char name [ 20 ];
} stud;
Run Code Online (Sandbox Code Playgroud)
是stud全局变量还是局部变量?
c++ ×11
c++11 ×3
c++14 ×3
atomic ×1
c ×1
c11 ×1
casting ×1
if-statement ×1
noexcept ×1
performance ×1
pointers ×1
polymorphism ×1
stdany ×1
struct ×1
templates ×1