我很想知道是否有人在C ++的多个编译器和平台上为STL对象开发兼容的接口层。
目标是支持STL类型作为一流或内在数据类型。
一般来说,模板是否存在一些固有的设计限制可以防止这种情况?这似乎是使用STL进行二进制分发的一个主要限制。
微软已经付出了努力,并没有真正关心C ++ STL支持是“一流的”。
开源不希望推广仅二进制分发,而是专注于使用单个编译器来解决问题,而不是10个不同版本的不匹配。
这似乎得到了我对Qt和其他库的经验的支持 - 它们通常为您将要使用的环境提供构建。例如,Qt 4.6和VS2008。
参考文献:
答案 0 :(得分:3)
我认为问题优先于你的理论:C ++没有指定ABI(应用程序二进制接口)。
实际上即使C没有,但作为C库只是函数的集合(可能是全局变量),ABI只是函数本身的名称。根据平台的不同,名称可能会以某种方式被破坏,但是,由于每个编译器都必须能够放置系统calss,所以一切都使用操作系统构建器的相同约定(在Windows中,_cdecl
只会导致前置_
到函数名。
但是C ++有重载,因此需要更复杂的修改方案。 到目前为止,编译器制造商之间尚未达成关于如何进行此类修改的协议。 从技术上讲,编译C ++静态库并将其链接到来自另一个编译器的C ++ OBJ是不可能的。 DLL也是如此。
由于编译器在编译的重载成员函数中都是不同的,因此没有人真正提供模板问题。
从技术上讲,它可以通过为每个参数类型引入重定向,并引入调度表但是......这使得模板化函数(在调用调度方面)与虚拟基础的虚函数没有区别,从而使模板性能变得类似于经典的OOP调度(虽然它可以限制代码膨胀......权衡并不总是显而易见的)
目前,似乎编译器制造商之间没有兴趣同意通用标准,因为它会牺牲每个制造商可能拥有的所有性能差异。
答案 1 :(得分:2)
C ++模板是编译时生成的代码 这意味着如果要使用模板化类,则必须包含其标头(声明),以便编译器可以为您需要的模板化类生成正确的代码。
因此,模板无法预编译为二进制文件。
其他库提供的是预编译的非模板化的基础实用程序类。
例如,C#泛型以dll或可执行文件的形式编译成IL代码 但IL代码就像另一种编程语言,所以这允许编译器从包含的库中读取泛型信息。.Net IL代码在运行时被编译成实际的二进制代码,因此运行时的编译器具有IL中需要的所有定义,以便为泛型生成正确的代码。
答案 2 :(得分:2)
我很想知道是否有人正在使用兼容的界面 跨多个编译器和平台的STL对象的层 C ++。
是的,我是。我正在开发一层标准化接口,您可以(除其他外)使用它来跨组件边界将二进制安全“托管”引用传递给STL,Boost或其他C ++类型的实例。该库(称为'Vex')将提供这些接口的实现以及适当的工厂来包装和解包流行的std ::或boost ::类型。此外,该库提供类似LINQ的查询运算符,用于过滤和操作我称之为Range
和RangeSource
的内容。图书馆还没有准备好“上市”,但我打算尽快发布一个早期的“预览版”...
示例:
com1
将对std::vector<uint32_t>
的引用传递给com2
:
com1:
class Com2 : public ICom1 {
std::vector<int> mVector;
virtual void Com2::SendDataTo(ICom1* pI)
{
pI->ReceiveData(Vex::Query::From(mVector) | Vex::Query::ToInterface());
}
};
com2:
class Com2 : public ICom2 {
virtual void Com2::ReceiveData(Vex::Ranges::IRandomAccessRange<uint32_t>* pItf)
{
std::deque<uint32_t> tTmp;
// filter even numbers, reverse order and process data with STL or Boost algorithms
Vex::Query::From(pItf)
| Vex::Query::Where([](uint32_t _) -> { return _ % 2 == 0; })
| Vex::Query::Reverse
| Vex::ToStlSequence(std::back_inserter(tTmp));
// use tTmp...
}
};
你会认识到与各种熟悉概念的关系:LINQ,Boost.Range,any_iterator和D's Ranges ......'Vex'的基本意图之一不是重新发明轮子 - 它只是添加了界面层加上一些必需的用于查询的基础结构和语法糖。
干杯,
保