【问题标题】:Should I use C++0x Features Now?我现在应该使用 C++0x 功能吗?
【发布时间】:2011-02-07 23:48:27
【问题描述】:

随着 VS 2010 的正式发布,我是否可以安全地开始在我的新代码中使用部分实现的 C++0x 功能集?

我现在感兴趣的功能都由 VC++ 2010 和最新版本的 GCC 实现。这是我必须支持的仅有的两个。

就第一句中提到的“安全性”而言:我可以开始使用这些特性(例如,lambda 函数)并且仍然保证我的代码将在 10 年内在正确符合 C++ 的编译器上编译0x什么时候正式发布?

我想我是在问 VC++ 2010 或 GCC 是否有可能像 VC++ 6 一样结束;它是在语言正式标准化之前发布的,因此允许编译格式错误的代码。

毕竟,微软确实说过“10 是新的 6”。 ;)

【问题讨论】:

  • 我不敢相信他们错过了“0x”标记。

标签: c++ gcc visual-studio-2010 language-features c++11


【解决方案1】:

如果您希望您的代码多年来保持不变,并希望它能够在编译器更改时不受干扰,我建议您坚持使用 C++98/03。

但是大多数代码都会随着时间的推移而维护,所以我认为这不是一个重要的考虑因素。我建议使用使您的代码更好的方法,并在升级编译器时计划一些工作。

【讨论】:

  • C++98 和 C++03 几乎相同,除了一些错误修复
【解决方案2】:

我已经发现有几个项目没有写入标准。例如,这是行不通的:



struct test {
  int operator()(int);
};

std::cout << typeid( std::result_of<test(int)>::type ).name() << std::endl;

根据 C++0x 上的维基百科站点,它应该。显然VS2010使用了result_of的TR1定义,这和C++0x会有的不同(基于decltype)。

另外,这不起作用:



std::bind<int>([](int i)->int {return i; });

它失败是因为调用 std::result_of(好吧,它的实现),失败是因为 lambda 类型没有 result_of typedef。这当然是您为绑定调用提供返回类型但显然它出于某种原因忽略它并继续自行搜索的原因。 bind 的 boost 版本按预期工作。出于这个原因,我们将继续在我们的项目中使用增强版的 bind。

另外,如果您在http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx?CommentPosted=true#commentmessage 上注意到,VS2010 尚未实现一些将影响 lambda 表达式的更改。我无法打破它们,但我没有使用嵌套的 lambda,而且可能永远不会。

您还应该记住 boost::shared_ptr 和 std::shared_ptr 是不兼容的。不足为奇,但如果您打算使用其中一种,您必须知道这一点......我不建议两者都使用,我们只会坚持使用 boost。

VS2010 中也没有 declval。不过制作起来很容易:


template < typename T > T&& declval();

使用示例:


template < typename T >
struct point
{
  T x,y;
};

template < typename T1, typename T2 >
point<decltype(declval<T1>() + declval<T2>())> operator + (point<T1> const& lh, point<T2> const& rh)
{
 ...
}

您还会在我上面链接的页面中注意到,我已经与开发团队的成员(或 PR 部分或其他)讨论了 decltype 中的错误。我提到的不止一个,所以我会同时展示两个:


template < typename T1, typename T2 >
auto operator + (point<T1> const& lh, point<T2> const& rh)
  -> point<decltype(lh.x + rh.x)>
{
...
}
point<int> x; point<double> y;
point<double> pt = x + y; // fails, operator + returned point<const double>

void f();
auto ptr = &f;

std::cout << typeid( decltype(*ptr) ).name() << std::endl;
std::cout << typeid( decltype(*&f) ).name() << std::endl; // should output the same thing...outputs void (*)()

另外...根据一些关于 decltype 和 result_of 的电子邮件交流,这应该可以工作:



std::result_of< decltype(f)() >::type x = f();

如果使用 decltype 的我自制的 std::result_of 版本,如果 decltype(f)() 表达式正常工作,这将起作用。它不是。给出一些关于函数返回函数的错误。您必须使用“decltype(&f)()”来使表达式起作用。

所以,当然……我们正在使用它。虽然有一些错误和废话。好处超过等待恕我直言。不要指望当标准出来时你的代码是标准的,未来的 MS 编译器可能会破坏它。

【讨论】:

    【解决方案3】:

    只要您对无法在旧编译器上编译的代码感到满意,那么您就没有什么可失去的,不妨利用新功能。

    【讨论】:

      【解决方案4】:

      许多重要的事情(即您通常会经常使用的事情)几乎都是一成不变的。我认为编写非标准代码的风险极低,特别是如果您坚持当前编译器上实现的规范子集。

      如需列出对功能的支持的好表,请转到here。就个人而言,auto 变量、r 值引用和 lambda 几乎都是要使用的重要功能,并且得到了很好的支持。

      【讨论】:

        【解决方案5】:

        我想我是在问 VC++ 2010 或 GCC 是否有可能像 VC++ 6 一样结束;它是在语言正式标准化之前发布的,因此允许编译格式错误的代码。

        恕我直言,有可能发生,但可能性很小。不仅是 MS,其他编译器供应商也已经支持一些 C++0x 特性,我希望标准委员会在这一点上对破坏兼容性非常小心。

        【讨论】:

          【解决方案6】:

          C++0X 功能集现在已经相当完善了,所以我会说去吧。根据维基百科,提案的最终草案应为done in august

          无论如何,很多东西都可以从 boost 中获得(实际上,很多 0X 的东西都来自 boost) - 请参阅 boost TR1。即使编译器不是完全 C++0X,您也可以通过 boost 重用这些功能。

          【讨论】:

          • 再读一遍。 FCD 已经出局,FDIS 计划在 2011 年 3 月之前进行投票。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-05-26
          • 2012-01-23
          • 1970-01-01
          • 2011-11-15
          • 2011-04-01
          • 1970-01-01
          • 2011-10-15
          相关资源
          最近更新 更多