面向 Visual Studio 2008 的 C++11 代码的兼容性
Compatibility for C++11 code targetting Visual Studio 2008
我正在就如何支持 C++11 之前的编译器进行内部辩论 - Visual Studio 2008。这是构建 Windows 2000 个盒子所必需的(不要问!)。
我正在使用一些 C++11 功能,例如 std::to_string、std::mutex 等。目前,我已经能够通过使用 boost
和 tr1
来编译低级项目,例如:
#if _MSC_VER == 1500
# include <boost/thread/lock_guard.hpp>
using boost::lock_guard;
# include <boost/thread/mutex.hpp>
using boost::mutex;
# include <memory>
using std::tr1::shared_ptr;
#else
# include <mutex>
using std::lock_guard;
using std::mutex;
# include <memory>
using std::shared_ptr;
using std::unique_ptr;
#endif
例如, 并将来源更改为 shared_ptr func_name()
而不是 std::shared_ptr func_name()
。远非完美,毫无疑问,很快就会有一些微妙的内部问题需要解决。
我现在正在尝试找出 std::to_string
,它不能那么容易地适应 boost 版本(在其他 类 中可能还有更多我还没有遇到的问题)。
据我所知,我有两种选择:
1) 咬紧牙关,预处理器分离所有向后兼容的代码。这将使 99% 的时间都不会使用的东西的代码变丑和变大——但实施起来会快得多。
2) 源自 std::string,并根据需要添加缺少的功能。对其他 classes/functions 重复上述步骤。这将需要 'using unknown classes' 给不熟悉该项目的人,以及额外的时间编码来填补这些空白,可能会出现错误,但这是最干净的解决方案。它也可以用于未来的兼容性修复。
换掉每一种类型并不是一项艰巨的任务,但我希望尽可能保留原始实现类型,尤其是当代码需要在 Linux 和 BSD 上 运行 时。我没有做任何难以向后移植的疯狂事情(没有元组、lambda 或其他在这种情况下会出现问题的事情)。
有没有人以前做过类似的事情并找到了一个很好的解决方案?
由于我没有足够的声誉来评论我会尝试给出答案。
std::to_string 是一个独立的函数,因此不需要派生。根据 speed/formatting 的重要性,您可以使用 boost::lexical_cast 或 std::stringstream 实现 my::to_string 模板函数。如果速度真的很重要,您应该投入更多时间并创建使用 std::sprintf.
的手动重载
这是第一种方式的例子:
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
namespace my {
template<typename T> std::string to_string(T val){
return boost::lexical_cast<std::string>(val);
}
}
int main(){
std::string foo = my::to_string(42.23);
std::cout << foo << std::endl;
return 0;
}
作为一般建议,我真的会尝试在一些低级别 类/ 文件中隐藏 os / 编译器特定的东西,并在那里使用任何你需要的东西。但尽可能将所有血淋淋的东西从您的应用程序代码中取出。
希望对您有所帮助!
我正在就如何支持 C++11 之前的编译器进行内部辩论 - Visual Studio 2008。这是构建 Windows 2000 个盒子所必需的(不要问!)。
我正在使用一些 C++11 功能,例如 std::to_string、std::mutex 等。目前,我已经能够通过使用 boost
和 tr1
来编译低级项目,例如:
#if _MSC_VER == 1500
# include <boost/thread/lock_guard.hpp>
using boost::lock_guard;
# include <boost/thread/mutex.hpp>
using boost::mutex;
# include <memory>
using std::tr1::shared_ptr;
#else
# include <mutex>
using std::lock_guard;
using std::mutex;
# include <memory>
using std::shared_ptr;
using std::unique_ptr;
#endif
例如, 并将来源更改为 shared_ptr func_name()
而不是 std::shared_ptr func_name()
。远非完美,毫无疑问,很快就会有一些微妙的内部问题需要解决。
我现在正在尝试找出 std::to_string
,它不能那么容易地适应 boost 版本(在其他 类 中可能还有更多我还没有遇到的问题)。
据我所知,我有两种选择:
1) 咬紧牙关,预处理器分离所有向后兼容的代码。这将使 99% 的时间都不会使用的东西的代码变丑和变大——但实施起来会快得多。
2) 源自 std::string,并根据需要添加缺少的功能。对其他 classes/functions 重复上述步骤。这将需要 'using unknown classes' 给不熟悉该项目的人,以及额外的时间编码来填补这些空白,可能会出现错误,但这是最干净的解决方案。它也可以用于未来的兼容性修复。
换掉每一种类型并不是一项艰巨的任务,但我希望尽可能保留原始实现类型,尤其是当代码需要在 Linux 和 BSD 上 运行 时。我没有做任何难以向后移植的疯狂事情(没有元组、lambda 或其他在这种情况下会出现问题的事情)。
有没有人以前做过类似的事情并找到了一个很好的解决方案?
由于我没有足够的声誉来评论我会尝试给出答案。
std::to_string 是一个独立的函数,因此不需要派生。根据 speed/formatting 的重要性,您可以使用 boost::lexical_cast 或 std::stringstream 实现 my::to_string 模板函数。如果速度真的很重要,您应该投入更多时间并创建使用 std::sprintf.
的手动重载这是第一种方式的例子:
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>
namespace my {
template<typename T> std::string to_string(T val){
return boost::lexical_cast<std::string>(val);
}
}
int main(){
std::string foo = my::to_string(42.23);
std::cout << foo << std::endl;
return 0;
}
作为一般建议,我真的会尝试在一些低级别 类/ 文件中隐藏 os / 编译器特定的东西,并在那里使用任何你需要的东西。但尽可能将所有血淋淋的东西从您的应用程序代码中取出。
希望对您有所帮助!