我最近从Microsoft编译器切换到GCC.在很多事情中,我注意到它std::make_unique变得不可用了.这显然是因为make_unique它不是C++ 11标准的一部分,而且恰好将Microsoft作为扩展包含在内.
我们计划很快转向C++ 14,但同时我写了这个"shim"函数并将其放入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)...));
}
}
Run Code Online (Sandbox Code Playgroud)
这解决了gcc上的问题.但是,我认为它会在微软方面引起问题,因为它将是一个重复的定义.
有没有办法将功能正确地填充到std中,这样就不会对不同的编译器/ C++标准造成麻烦?我环顾四周,没有拿出任何东西.对于特定的标准功能,我想也许就像一个包含守卫?
#ifndef MAKE_UNIQUE_DEFINED
#define MAKE_UNIQUE_DEFINED
// Define make_unique
#endif
Run Code Online (Sandbox Code Playgroud)
可悲的是,它似乎std没有定义包含特定功能的警卫.还有什么我可以做的,以使这更正确和编译器/ C++标准不可知?
你可以,实际上.只需将帖子中提到的两个条件转换为条件宏定义:
#if defined(_MSC_VER) && __cplusplus == 201103L
# define MAKE_UNIQUE_DEFINED 1
#endif
Run Code Online (Sandbox Code Playgroud)
_MSC_VER检查TU是用MSVC编译的.这是他们预定义的宏之一.您可以使用它来进一步细化检查,因为它是MSVC的编码版本号.__cplusplus TU编译为C++ 11时的值(这是跨平台的标准).__cplusplus没有为您正确定义(因为Microsoft),您可以使用_MSVC_LANG宏代替它.正如您最初计划的那样,上面的内容可用于包裹您的"垫片".或者,或者与这些版本相关的任何其他MSVC扩展,事实上.
作为替代方案,避免重新打开std命名空间(禁止否).您可以使用命名空间将定义显示在安全的位置,并控制程序如何解释它:
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
}
Run Code Online (Sandbox Code Playgroud)
然后宏只在那里控制extended_std::make_unique所指的内容.它要么创建命名空间inline,要将其内容倾注到封闭的内容中.或者添加一个使用声明std::make_unique.
| 归档时间: |
|
| 查看次数: |
542 次 |
| 最近记录: |