如何将功能正确地填充到 std 中? [英] How to correctly shim functionality into std?

查看:29
本文介绍了如何将功能正确地填充到 std 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从 Microsoft 编译器切换到 GCC.在许多事情中,我注意到 std::make_unique 变得不可用.这显然是因为 make_unique 不是 C++11 标准的一部分,而微软恰好将其作为扩展包含在内.

I recently switched from the Microsoft compiler to GCC. Among many things, I noticed that std::make_unique became unavailable. This is apparently because make_unique is not part of C++11 standard, and Microsoft just happened to include it as an extension.

我们计划很快转移到 C++14,但同时我写了这个填充"函数,并将它放入 std.

We are planning to move to C++14 soon, but in the mean while I wrote this "shim" function, and put it into std.

namespace std
{
    template<typename T, typename... TArgs>
    unique_ptr<T> make_unique(TArgs&&... args)
    {
        return std::unique_ptr<T>(new T(std::forward<TArgs>(args)...));
    }
}

这在 gcc 上解决了这个问题.但是,我想这会在 Microsoft 方面引起问题,因为它是一个重复的定义.

This solved that problem on gcc. However, I imagine it would cause problems back at Microsoft's side, since it would be a duplicate definition.

有没有办法将功能正确地填充到 std 中,这样它就不会在不同的编译器/C++ 标准上造成麻烦?我环顾四周,并没有想出什么.我想对于特定的标准功能,可能类似于包含守卫?

Is there a way to correctly shim functionality into std, so that it wouldn't cause trouble on different compilers / C++ standards? I looked around and didn't come up with anything. I thought maybe something like an include guard, for specific standard functions?

#ifndef MAKE_UNIQUE_DEFINED
#define MAKE_UNIQUE_DEFINED
// Define make_unique
#endif

遗憾的是,std 似乎没有为特定功能定义包含保护.我还能做些什么来使这更正确并且与编译器/C++ 标准无关?

Sadly it seems std doesn't define include guards for specific functions. Is there anything else I can do to make this more correct and compiler / c++ standard agnostic?

推荐答案

实际上可以.只需将您在帖子中提到的两个条件转换为条件宏定义:

You can, actually. Just turn the two conditions you mentioned in your post to a conditional macro definition:

#if defined(_MSC_VER) && __cplusplus == 201103L
#  define MAKE_UNIQUE_DEFINED 1
#endif

  • _MSC_VER 检查 TU 是否使用 MSVC 编译.这是他们预定义的宏之一.您可以使用它来进一步细化检查,因为它是 MSVC 的编码版本号.
  • 201103L 是 __cplusplus 的值当 TU 编译为 C++11 时(这是标准的,跨平台).
  • 如果没有为您正确定义 __cplusplus(因为 Microsoft),您可以使用 _MSVC_LANG 宏代替.
    • _MSC_VER checks the TU is compiled with MSVC. It's one of their predefined macros. You can use it to further refine the check, since it's the encoded version number of MSVC.
    • 201103L is the value of __cplusplus when the TU is compiled as C++11 (this is standard, across platforms).
    • In case __cplusplus isn't correctly defined for you (because Microsoft), you can use the _MSVC_LANG macro in its stead.
    • 以上内容可用于包装您的垫片",正如您最初计划的那样.或者事实上与这些版本相关的任何其他 MSVC 扩展.

      The above can be used to wrap your "shim", as you originally planned. Or any other MSVC extension that pertains to these versions, as a matter of fact.

      作为替代方案,避免重新打开 std 命名空间(禁忌).您可以使用命名空间将定义放在一个安全的地方,并控制您的程序如何解释它:

      As an alternative, to avoid reopening the std namespace (a no-no). You could use namespacing to have the definition present in a safe place, and control how your program interprets it:

      namespace extended_std {
        #ifdef MAKE_UNIQUE_DEFINED
          inline namespace
        #else
          namespace
        #endif
        shim {
           // your definition goes here
        }
      
        #ifndef MAKE_UNIQUE_DEFINED
        using std::make_unique;
        #endif
      } 
      

      该宏仅用于控制 extended_std::make_unique 所指的内容.它要么使命名空间 inline,将其内容倒入封闭的命名空间中.或者为 std::make_unique 添加 using 声明.

      The macro is then only there to control what extended_std::make_unique refers to. It either makes the namespace inline, pouring its content into the enclosing one. Or adds a using declaration for std::make_unique.

      这篇关于如何将功能正确地填充到 std 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆