小编abi*_*bir的帖子

类型C++支持的表达式语法是什么?

我正在使用一个带有一组整数的模板化类.代码就像,

template<unsigned... Idx>
struct work{ ... };
Run Code Online (Sandbox Code Playgroud)

然后我意识到,用户可能需要提供一组整数或一系列整数.所以,我改变了语法,以支持实例化,如,

work<indexes<1,3,2,4> > //instead of work<1,3,2,4>
work<span<1,4> > //same as work<1,2,3,4> 
Run Code Online (Sandbox Code Playgroud)

同时,在C++,我们有大量的运营商,并且可以被用于配制异国表达式模板(比方说boost::xpressive,boost::lambda,boost::spirit等等),用于类型操纵可能性要少得多.

在Sean Parent的一个boostcon主题演讲中,他指出一个仍然不能写pair<int>的表示a pair of integers.在我的persinal库中,我做了一个语法,就像tuple<int[3]>表示一个3个整数的元组,而不是在类型参数中写一个带有3个int的元组,注意到我没有在任何地方写一个原始数组作为元组参数!(注意:std::array<int,3>与上面不一样,因为std :: array不能存储引用,tuple可以说std::tuple<int&,int&,int&>,可以)

所以,我想知道我能写的不同类型的"类型表达式"是什么?

到目前为止,我可以想到对象类型,函数类型,引用类型,有/无cv修饰符,指针等

    template<class T>
    struct tpl;

    using t1 = tpl<int>;//simple type
    //function (can have function pointer/reference also) 
    // e.g. void(*)(int,float) or void(&)(int,float)
    using t2 = tpl<void(int,float)>;
    //array can have pointer / reference also
    //e.g. int(&)[4] or …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

16
推荐指数
2
解决办法
587
查看次数

是否可以使用非递归的at_c实现?

很久以前我看过一个非递归实现来从类型序列/值序列中获取最后一个值/类型.它有一个很好的属性,实例化的模板数量是序列包含的元素数量的独立(和常量).

实现很简单,如下所示

// a struct that eats anything and everything
struct eat { template<class T> eat(T&&) {} }; 
// generates V matching with U
template<class U, class V> struct match { using type = V; }; 
template<class... X> struct back_ 
{ 
    template<class U>
    static U&& get(typename match<X, eat>::type..., U&& u)
    {
        return static_cast<U&&>(u); // forward
    }
};
// simple macro to avoid repetition for trailing return type.
#define RETURNS(exp) -> decltype(exp) { return exp; }
// get the last value …
Run Code Online (Sandbox Code Playgroud)

c++ recursion templates variadic-templates c++11

14
推荐指数
1
解决办法
426
查看次数

c ++隐式复制和移动构造函数背后的基本原理?

我对c ++隐式复制构造函数的理解类似于

T(T const& x) : 
    base1(x), base2(x) ... , 
    var1(x.var1), var2(x.var2)...
{}
Run Code Online (Sandbox Code Playgroud)

移动构造函数,复制和移动赋值也遵循类似的模式.

为什么没有定义类似于以下内容?

T(T const& x) : 
    base1(static_cast<base1 const&>(x)),
    base2(static_cast<base2 const&>(x)) ... , 
    var1(x.var1), var2(x.var2)...
{}
Run Code Online (Sandbox Code Playgroud)

我有一个类具有隐式复制/移动构造函数/赋值运算符,以及一些转换构造函数.我把工作委托给了一些实现类.

class common_work //common implementation of many work like classes
{
   common_work(common_work const&) = default;
   common_work(common_work&&) = default;// ... implicit constructors work for me.
   //a forwarding constructor which can take many work like objects
   template<class T, enable_if<work_like<T> > >
   common_work(T&& x) { ... }
};
class work1 //one of the implementation …
Run Code Online (Sandbox Code Playgroud)

c++ constructor assignment-operator perfect-forwarding c++11

12
推荐指数
1
解决办法
502
查看次数

aligned_storage的基本用法是什么?

std :: tr1 :: aligned_storage的基本用法是什么?它可以用作数据类型Foo的自动存储器,如下所示吗?

   struct Foo{...};
   std::tr1::aligned_storage<sizeof(Foo)
        ,std::tr1::alignment_of<Foo>::value >::type buf;
   Foo* f = new (reinterpret_cast<void*>(&buf)) Foo();
   f->~Foo();
Run Code Online (Sandbox Code Playgroud)

如果是这样,那么在buf中存储多个Foo就像,

    std::tr1::aligned_storage<5*sizeof(Foo)
            ,std::tr1::alignment_of<Foo>::value >::type buf;
    Foo* p = reinterpret_cast<Foo*>(&buf);
    for(int i = 0; i!= 5; ++i,++p)
    {
        Foo* f = new (p) Foo();
    }
Run Code Online (Sandbox Code Playgroud)

他们是有效的计划吗?它还有其他用例吗?Google搜索只会生成有关aligned_storage的文档,但关于它的使用情况却很少.

c++

11
推荐指数
1
解决办法
4035
查看次数

为什么统一初始化语法仅适用于对象?

在c ++ 11中,我们为对象提供了很好的统一初始化语法.为什么它不扩展到初始化非对象类型?

这有什么语法歧义,还是我问的一些愚蠢的问题?

例:

struct s{ int k;};
s s1{1}; //ok (object initialization)
s const& s3{3};  //ok (object initialization)
s& s2{s1};  //error (reference initialization)
Run Code Online (Sandbox Code Playgroud)

一个更有用的例子:

struct t{ t(t const& x) : k(x.k){} int k;};
struct c
{
  c(t& x1,t& x2) 
    : s1_{x1} //error (reference initialization)
    , s2_{x2} //ok (object initialization)
   {}
 t& s1_;
 t s2_;
};
Run Code Online (Sandbox Code Playgroud)

另一个 :

template<class T>
T get()
{
   return T{};
}

//ok (object initialization)
get<int>(); 
//error (void initialization? I do not know terminology for …
Run Code Online (Sandbox Code Playgroud)

c++ uniform-initialization c++11

9
推荐指数
1
解决办法
218
查看次数

typedef和不完整类型

最近,当我在代码中更改了某些容器​​,分配器时,我遇到了很多typedef和不完整类型的问题.

我之前有过的

struct foo;//incomplete type.
typedef std::vector<foo> all_foos;
typedef all_foos::reference foo_ref;
Run Code Online (Sandbox Code Playgroud)

虽然不完全不确定上述行是否合法,但这适用于我使用的每个实现.当我以为我可以完成这项工作时std::tr1::array,改变了以上两行

typedef std::tr1::array<foo,5> all_foos;
typedef all_foos::reference foo_ref;
Run Code Online (Sandbox Code Playgroud)

这里的一切都中断了,因为编译器试图实例化array并且因为foo类型不完整而失败.我所需要的是foo对数组的"其他部分"的引用,而不是很感兴趣.当我创建这样的数组时,foo肯定会完全可用.

当typedef std::allocator<foo>::pointer foo_ptr被typedef替换时,同样的问题stack_alloc<foo,10>::pointer foo_ptr.其中,stack_alloc实现像

template<typename T,unsigned N>
struct stack_alloc
{
  typedef T* pointer;
  typedef std::tr1::aligned_storage<sizeof(T)*N, std::tr1::alignment_of<T>::value> buffer;
};
Run Code Online (Sandbox Code Playgroud)

假定该,value_type,pointer,reference,iterator等不依赖于的完整性T,以及明知类不能没有完全类型实例化,类型定义怎么这么能在独立于特定的容器或分配器的通用方式进行?

注意:

  • 仅仅为了完整性,在"真实"代码中我使用一个小的本地内存vector而不是替换它std::array,尽管问题仍然存在.
  • stack_alloc 代码远未完成,只显示问题的一部分.
  • 我知道数组,sizeof等需要完整的类型.但我不是创建all_foos不完整类型的对象foo.
  • 我的断言是指针,引用等不应该依赖于类型的完整性.否则构造就像struct foo{ foo_ptr p;};无法定义.虽然可能 …

c++ typedef

8
推荐指数
1
解决办法
3439
查看次数

仅在一端生长的序列的合适名称

有几次我在一个vector或另一个可变序列(序列适配器)上使用受限制的接口,它只允许push_backclear.它有一些很好的属性,例如,迭代器可以基于索引来设计,索引总是稳定的(比如stable_vector但也有元素连续性),因此可以存储而不用担心失效,除非它被清除.

我想用一个适配器类来代替vector或其他序列直接强调接口(以及防止使用不支持的操作,如任何意外的错误insert,erase等等).

是否存在与此append_only序列匹配的现有ADT ?否则任何人都可以推荐这个序列适配器的合适名称?

c++ containers sequence

8
推荐指数
1
解决办法
136
查看次数

迁移到c ++ 11

我正在研究一种主要使用C++作为其核心组件的产品.虽然它使用Visual C++作为Windows平台的主要编译器及其编辑器和调试器作为主要开发环境,但未使用任何Microsoft特定技术.对于其他平台,它使用gcc进行编译.

我的代码库大量使用模拟的右值引用(使用Boost移动库),可变参数模板(使用Boost处理器),在某些情况下使用表达式模板.

我很想转换到C++ 11来获得更清晰的代码库,使用rvalue引用,完美转发,默认和删除构造函数,可变参数模板以及auto和decltype.

如果我这样做,我可能会对现有代码进行一些修改以简化它(使用模板别名和constexpr).在这种情况下,我必须使用mingw切换到Windows平台的gcc,因为Visual Studio没有默认和删除的实现,以及可变参数模板.另外,我必须切换到gdb作为调试器和不同的代码编辑器.

对我来说,代码简单性和性能方面的好处看起来很大,但稳定性,可用性(在某些平台上如Android),调试(从Visual Studio迁移到gdb,因为我们有许多为Visual Studio调试器开发的可视化工具)和代码编辑器(对于大量的模板代码而言,我没有太多使用自动完成,重构等,而Codelite,Codeblocks,QtCreator与我们的构建系统配合良好)是一些问题.

我想知道是否有任何中型/大型项目(商业或开源)使用/打算使用上述任何C++ 11功能?这种迁移需要多少努力?

任何实践经验,技巧或智慧的话语都会帮助我做出决定.

c++ c++11

7
推荐指数
1
解决办法
1621
查看次数

catch站点的异常常见用法是什么?

我对异常处理的理解非常有限.虽然我发现很容易抛出异常(或者我可以将它打包expected<T>用于以后的消费),但我对如何处理异常几乎一无所知.

目前我的知识仅限于

  • 清理我自己的资源并重新抛出要在适当位置处理的异常.例如

    ptr p = alloc.allocate(n);
    try
    {
       uninitialized_copy(first,last,p);//atomic granularity, all or none
    }
    catch(...)
    {
        alloc.deallocate(p,n);
        throw;
    }
    
    Run Code Online (Sandbox Code Playgroud)

但我想,这可以在一个RAII模式中等效地转换为

alloc_guard<ptr> p{alloc.allocate(n)};
uninitialized_copy(first,last,p.get());
p.commit();
Run Code Online (Sandbox Code Playgroud)
  • 在顶层捕获异常,撰写并打印一条好消息并退出.eg

    int main(int argc,char** argv)
    {
       try
       {
           app_t the_app(argc,argv);
           the_app.run();
       }
       catch(std::runtime_error& e)
       {
          //instead of what, I can also compose the mesage here based on locale.
          std::cout<<e.what()<<std::endl;
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)

所以,我所做的就是处于顶级功能,例如main捕获异常并打印相应的消息并关闭.

在使用各种外部库作为实现的后端实现具有一组良好API的库时,我意识到第三方库异常是我的API规范的一部分,因为它们跨越我的库边界并落在用户代码中!

因此,我的库API泄露了我用于用户代码的外部库(并且每个库都有自己的异常层次结构)的所有异常.

这导致了我的问题,当我发现任何异常时可以做些什么?

进一步来说,

  • 我可以将捕获的异常从外部库转换为我自己的异常并以通用方式抛出(比如第三方库异常层次结构和我的异常API之间的映射是作为a提供的mpl::map)吗?
  • 我可以做一些比打印消息/调用堆栈更有用的东西,比如使用不同的输入参数恢复抛出站点的功能(比如当我得到那个file_not_found或者disk_error,用另一个文件重新运行该函数)?
  • 还有其他有价值的模式吗?

谢谢

c++ exception-handling exception try-catch c++11

7
推荐指数
1
解决办法
582
查看次数

为什么在rvalue的情况下转发引用不演绎为rvalue引用?

我知道,给定一个初始化转发/通用引用的表达式,就可以推断出lvalues是type,T&而rvalues是type T(而不是T&&)。

因此,为了只允许右值,需要写

template<class T, enable_if<not_<is_lvalue_reference<T> >,OtherConds... > = yes>
void foo(T&& x) {}
Run Code Online (Sandbox Code Playgroud)

并不是,

template<class T, enable_if<is_rvalue_reference<T>,OtherConds... > = yes>
void foo(T&& x) {}
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么对于转发引用,右值被推导为类型T而不是T&&?我猜想,如果推论为,T&&则相同的引用折叠规则也与T&& &&相同T&&

c++ templates perfect-forwarding c++11 template-argument-deduction

6
推荐指数
1
解决办法
405
查看次数