有没有办法可移植地检测使用宏包括标准头? [英] Is there a way to detect portably that a standard header is included using macros?

查看:133
本文介绍了有没有办法可移植地检测使用宏包括标准头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要等价于 boost :: swap ,在我的环境中,标准头文件可以,也可以不包括。取决于项目许可和其他东西。

我想使保护检测器保护的代码部分:



让我们考虑一个编译单元。

项目特定,前述潜力包括:

  #include< algorithm> //(或C ++ 11项目的< utility>)

我的交换实用程序头:

 命名空间MyCompany 
{
template< class T1,class T2>
void swap(T1& left,T2& right)
{
#ifdef _ALGORITHM_ //你的想法。
std :: swap(left,right);
#else
// fallback impl
#endif
}
}

我简化了因为我们不是在说这里的ADL招式的细节,但它会包括。

在这里参考我在说什么,但这与此问题无关:

http:// www.boost.org/doc/libs/1_57_0/boost/core/swap.hpp



所以这个问题是关于,如何检测标准标题包含 _ALGORITHM _ guard存在于visual studio提供的标题中,但我在中无处可见http://www.cplusplus.com/reference/algorithm/ ,它应该有任何我可以检查的宏。



最后一个注释:这个问题有点偏见,我真正想要的是检测 std :: swap 函数的存在,而不是标题。)

解决方案

你有一个选项,使你的重载更糟糕的匹配比替代。然后,只有当它们不存在时,才会选择您的版本:

  #if 0 
#include< ;算法>
using std :: swap;
#endif

template< typename T>
struct ForceLessSpecialized {
typedef T TYPE;
};

template< typename T>
void swap(T& typename ForceLessSpecialized< T> :: TYPE&){
}

void bar(){
int i;
swap(i,i);
}

发生了什么:
$ b

当有两个候选函数模板特化时,编译器执行函数模板的部分排序('03 14.5.5.2)。



对于每个模板,我们将使用虚拟参数 T1 T2 ,我们使用这些类型创建虚拟参数列表:

  // std :: swd参数列表
(T1&,T1&)

//我们的交换参数列表
typename ForceLessSpecialized< T2> :: TYPE&)

c $ c> std :: swap 给出:

 从第一个参数扣除:T == T1 
从第二个参数中扣除:非扣除上下文

推导出 T T1 并且扣除已成功。



使用我们交换的虚拟参数来专门处理 std :: swap



从第一个参数中扣除:T == T2
从第二个参数中扣除:T == ForceLessSpecialized< T2> :: TYPE

T 的推导类型不一样,因此因此, std :: swap 的合成参数可用于专门化我们的模板,但我们的模板的合成参数不能用于专门化 std :: swap std :: swap 被视为更专业,因此赢得部分ordernig。


I want to make an equivalent to boost::swap and in my environment, standard headers can, or cannot be included. Depending on project licencing and other stuff.
I'd like to make portions of the code protected by guard detectors:

Let's consider one compilation unit.
project specific, afore-written potential includes:

#include <algorithm> // (or <utility> for C++11 projects)

later in project code included from my swap utility header:

namespace MyCompany
{
  template<class T1, class T2>
  void swap(T1& left, T2& right)
  {
     #ifdef _ALGORITHM_   // you get the idea.
       std::swap(left, right);
     #else
       // fallback impl
     #endif
  }
}

I simplified because we are not talking about details of the ADL trick here, but it will get included.
here for the reference of what I am talking about, but this is irrelevant to this question:
http://www.boost.org/doc/libs/1_57_0/boost/core/swap.hpp

So this question is about, how can I detect standard header inclusion ? the _ALGORITHM_ guard is present in visual studio provided header, but I read nowhere on http://www.cplusplus.com/reference/algorithm/ that it should have any macro that I can check.

(final note: this question is a little bit XY biased. What I really want is to detect the presence of the std::swap function, not the header.)

解决方案

One option you have it to make your overload a "worse match" than the alternatives. Then, only if they don't already exist will your version be selected:

#if 0
#include <algorithm>
using std::swap;
#endif

template <typename T>
struct ForceLessSpecialized {
  typedef T TYPE;
};

template <typename T>
void swap (T &, typename ForceLessSpecialized<T>::TYPE &) {
}

void bar () {
  int i;
  swap (i, i);
}  

What's happening:

When there are two candidate function template specializations, the compiler performs "Partial ordering of function templates"('03 14.5.5.2). This checks if the function template parameters of the one template can be used to specialize the other.

For each template we'll use dummy parameters T1 and T2 and we create dummy argument lists using these types:

// std::swap argument list
( T1 &  , T1 & )

// our swap argument list
( T2 &, typename ForceLessSpecialized<T2>::TYPE & )

Specializing our swap using the dummy arguments from std::swap gives:

Deduction from First parameter:  T == T1
Deduction from Second parameter:  Non Deduced Context

The deduced T is T1 and deduction has succeeded.

Specializing std::swap using the dummy arguments for our swap gives:

Deduction from First parameter:  T == T2
Deduction from Second parameter:  T == ForceLessSpecialized<T2>::TYPE

The deduced types for T are not the same, and so this is considered a deduction failure.

Therefore, the synthesized arguments of std::swap can be used to specialize our template, but the synthesized arguments of our template cannot be used to specialize std::swap. std::swap is seen as being more specialized and so wins the partial ordernig.

这篇关于有没有办法可移植地检测使用宏包括标准头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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