小编ltj*_*jax的帖子

松耦合隐式转换

类型在语义上等效时,隐式转换非常有用.例如,假设两个库以相同的方式实现类型,但在不同的命名空间中.或者只是一种大多数相同的类型,除了一些语义糖在这里和那里.现在,您无法将一种类型传递给设计为使用另一种的函数(在其中一个库中),除非该函数是模板.如果不是,你必须以某种方式将一种类型转换为另一种类型.这应该是微不足道的(或者其他类型在后面都不是那么相同!)但是调用转换显然会使代码膨胀,而且函数调用几乎毫无意义.虽然这样的转换函数实际上可能会复制一些值,但它们从高级"程序员"的角度来看基本上什么都不做.

隐式转换构造函数和运算符显然可以提供帮助,但它们引入了耦合,因此其中一种类型必须知道另一种类型.通常,至少在处理库时,情况并非如此,因为其中一种类型的存在使另一种类型变得冗余.此外,您不能总是更改库.

现在我看到有关如何在用户代码中进行隐式转换的两个选项:

  1. 第一个是提供代理类型,它为所有涉及的类型实现转换操作符和转换构造函数(和赋值),并始终使用它.

  2. 第二个需要对库进行最小的更改,但允许很大的灵活性:为每个可以在外部选择启用的相关类型添加转换构造函数.

例如,对于类型A添加构造函数:

template <class T> A(
  const T& src,
  typename boost::enable_if<conversion_enabled<T,A>>::type* ignore=0
)
{
  *this = convert(src);
}
Run Code Online (Sandbox Code Playgroud)

和一个模板

template <class X, class Y>
struct conversion_enabled : public boost::mpl::false_ {};
Run Code Online (Sandbox Code Playgroud)

默认情况下禁用隐式转换.

然后要启用两种类型之间的转换,请专门化模板:

template <> struct conversion_enabled<OtherA, A> : public boost::mpl::true_ {};
Run Code Online (Sandbox Code Playgroud)

并实现一个convert可以通过ADL找到的函数.

我个人更喜欢使用第二种变体,除非有强烈的反对意见.

现在回答实际问题:关联隐式转换类型的首选方法是什么?我的建议是好主意吗?两种方法都有任何缺点吗?允许这样的转换是危险的吗?如果库类实现者通常会提供第二种方法,那么它们的类型很可能会被软件复制,而这些软件很可能与它们一起使用(我在考虑使用3d渲染中间件,其中大多数软件包实现了3D向量).

c++ boost-mpl enable-if

25
推荐指数
1
解决办法
1061
查看次数

将当前时间作为YYYY-MM-DD-HH-MM-SS字符串

我试图以优雅的方式将当前时间作为"YYYY-MM-DD-HH-MM-SS"格式化字符串.我可以从Boost的"Date Time"库获取ISO格式的当前时间,但它有其他分隔字符串,这对我不起作用(我在文件名中使用它).当然我可以直接替换分隔字符串,但感觉有一种更好的方法可以使用日期时间的格式化选项.有这样的方式,如果有的话,我该如何使用它?

c++ boost string-formatting boost-date-time

19
推荐指数
1
解决办法
3万
查看次数

使用Boost.Asio链接异步Lambda?

我发现自己编写的代码基本上是这样的:

using boost::system::error_code;

socket.async_connect(endpoint, [&](error_code Error)
{
  if (Error)
  {
    print_error(Error);
    return;
  }

  // Read header
  socket.async_read(socket, somebuffer, [&](error_code Error, std::size_t N)
  {
    if (Error)
    {
      print_error(Error);
      return;
    }

    // Read actual data
    socket.async_read(socket, somebuffer, [&](error_code Error, std::size_t N)
    {
      // Same here...
    });
  });
};
Run Code Online (Sandbox Code Playgroud)

所以基本上我在回调中的回调中嵌套回调,而逻辑很简单并且是"线性的".

是否有更优雅的方式来编写它,以便代码是本地的和有序的?

c++ lambda boost-asio

17
推荐指数
1
解决办法
2993
查看次数

嵌套未命名的命名空间

这两个未命名的命名空间的嵌套用法之间是否存在功能差异:

namespace A { namespace {
  void foo() {/*...*/}
}}
Run Code Online (Sandbox Code Playgroud)

namespace { namespace A {
  void foo() {/*...*/}
}}}
Run Code Online (Sandbox Code Playgroud)

据我所知,两个foos都将获得每个编译单元的内部唯一标识符,并且可以使用A::foo- 但是有一个微妙的或不那么微妙的区别,我没有看到?

c++ namespaces

15
推荐指数
1
解决办法
1937
查看次数

跳过迭代器

我有一系列值,我想传递给一(iterator begin, iterator end)对函数.但是,我只希望处理原始序列中的每个第二个元素.

有没有一种很好的方法使用Standard-Lib/Boost创建一个迭代器外观,允许我传入原始序列?我认为这样的简单事情已经在boost迭代器或范围库中,但我没有找到任何东西.

或者我错过了另一个完全明显的方法来做到这一点?当然,我知道我总是可以选择将值复制到另一个序列,但这不是我想要做的.

编辑:我知道filter_iterator,但过滤值 - 它不会改变迭代进展的方式.

c++ boost stl boost-iterators

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

具有继承的嵌套类的名称查找

这保证是有效的:

struct A
{
  struct Gold {};
};

struct B : public A
{
  typedef Gold BaseGold;
  struct Gold {};
};

struct C : public B
{
  typedef Gold BaseGold;
  struct Gold {};
};

static_assert(is_same<B::BaseGold, A::Gold>::value, "Not the right treasure!");
static_assert(is_same<C::BaseGold, B::Gold>::value, "Not the right treasure!");
Run Code Online (Sandbox Code Playgroud)

它似乎适用于VS2010.显然它依赖于微妙的声明顺序/名称查找规则,所以我想知道标准在这个问题上说了什么......

c++ inheritance name-lookup

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

使用luabind和std :: shared_ptr继承

我有一个依赖std::shared_ptr很多的API(一个特定的GUI库),即它们通常用作函数参数并存储在其他对象中.例如,容器小部件(例如拆分器和框)将其子小部件存储在shared_ptrs中.现在我想通过luabind将此API映射到Lua.在理想的世界中,Luabind将在shared_ptrs中创建新对象,并允许我将这些对象直接传递给采用shared_ptr参数的函数.这似乎适用于单个类,例如:

luabind::class_<Button, std::shared_ptr<Button>>("Button")
Run Code Online (Sandbox Code Playgroud)

虽然我这样声明,但我可以公开和使用像void foo(std::shared_ptr<Button> const&).

现在,luabind手册提到为了使用类的层次结构,我必须对层次结构中的所有类使用相同的shared_ptr模板实例,例如

luabind::class_<BaseWidget, std::shared_ptr<BaseWidget>>("BaseWidget"),
luabind::class_<Button, BaseWidget, std::shared_ptr<BaseWidget>>("Button")
Run Code Online (Sandbox Code Playgroud)

现在我再也无法打电话了foo- 它将无法从Lua找到该功能.我可以以某种方式让luabind继续支持shared_ptrs中的传递按钮吗?此外,我想知道为什么luabind要求您对层次结构中的所有类使用相同的智能指针,而不是它们只能转换为基类指针.

c++ lua shared-ptr luabind c++11

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

shared_ptr和循环引用

我正在尝试使用循环引用boost::shared_ptr,并设计了以下示例:

class A{ // Trivial class
public:
    i32 i;
    A(){}
    A(i32 a):i(a){}
    ~A(){
        cout<<"~A : "<<i<<endl;
    }
};

shared_ptr<A> changeI(shared_ptr<A> s){
    s->i++;
    cout<<s.use_count()<<'\n';

    return s;
}

int main() {

    shared_ptr<A> p1 = make_shared<A>(3);
    shared_ptr<A> p2 = p1;
    shared_ptr<A> p3 = p2;
    shared_ptr<A> p4 = p3;

    p1 = p4; // 1) 1st cyclic ref.
    cout<<p1.use_count()<<'\n';

    p1 = changeI(p4); // 2) 2nd cyclic ref.

    cout<<p1.use_count()<<'\n';

//  putchar('\n');
    cout<<endl;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

4
5
4

~A : 4
Run Code Online (Sandbox Code Playgroud)

是不是我误解了所提到的循环引用boost::shared_ptr?因为,我预计间接引用的不同输出思维p1 …

c++ shared-ptr weak-ptr cyclic-reference

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

四面体网格中的点位置

四面体网格中的点位置是否有任何经过验证的数据结构,其中四面体都是不相交的,但彼此"接触"?即大多数面孔都是正好两个四面体的面孔.

按位置我的意思是我想找出给定点位于哪个四面体中,或者它是否位于任何四面体中.

到目前为止,我尝试过:

  1. 一个简单的KD树.这对我的需求来说太慢了,因为平均树深非常高,我仍然有很多单独的四面体在每片叶子中进行测试.

  2. 一个网格,包含每个单元格的所有交叉四面体.这似乎工作得更好,但仍然不够快.首先,网格包含许多空单元格,因为我的整体网格不是非常"四四方方".其次,大多数实际上含有四面体的细胞确实含有大量细胞(10+).我想这是因为很多四面体共享每个顶点,一旦顶点在一个单元格中,所有相邻的四面体也是如此.

关于输入数据的一些进一步信息:网格通常不是凸的并且可以具有孔或内含物.虽然最后两个有点不太可能,但我必须处理它们,如果没有(昂贵和复杂的?)预处理,这使得"行走"变得不可能.

algorithm computational-geometry

8
推荐指数
2
解决办法
1455
查看次数

有没有办法将lambda的签名推断为mpl序列?

有没有办法将c ++ 0x lambda的签名,结果和参数类型推断为Boost.MPL序列,例如boost::mpl::vector?例如,对于lambda

[]( float a, int b ) -> void { std::cout << a << b << std::endl; }
Run Code Online (Sandbox Code Playgroud)

我想得到一个boost::mpl::vector<void,float,int>.

c++ lambda metaprogramming boost-mpl c++11

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