有条件地启用非模板功能C ++

J. *_*rez 5 c++ portability mpi c++11

背景

我正在使用MPI进行高性能计算中的C ++项目。我有一个函数,其中包含一些不同的重载,可用于将不同的类型转换为字符串:

void append(std::string& s, int value);
void append(std::string& s, void* value);
void append(std::string& s, MPI_Request request); 
Run Code Online (Sandbox Code Playgroud)

当我使用Open MPI时,这工作正常。在OpenMPI中,MPI_Request是的别名ompi_request_t*,因此每个重载都有不同的签名。

但是,最近,我尝试使用MPICH编译代码。在MPICH中,MPI_Request是的别名int,结果是上述代码由于两次append定义而无法编译int

/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp: At global scope:
/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp:28:6: error: redefinition of ‘void append(std::__cxx11::string&, int)’
 void append(std::string& s, int i) { s.append(std::to_string(i)); }
      ^~~
/home/me/NimbleSM/src/mpi-buckets/src/mpi_err.hpp:17:6: note: ‘void append(std::__cxx11::string&, MPI_Request)’ previously defined here
 void append(std::string& s, MPI_Request request)
Run Code Online (Sandbox Code Playgroud)

我应该如何编写append(std::string&, MPI_Request),以使编译器在MPI_Request定义为时忽略它int,而在MPI_Request是库类型时识别它?

尝试的解决方案:enable_if失败

我试图写一个基于的解决方案std::enable_if,该函数仅在MPI_Request类型不同于时才启用int

auto append(std::string& s, MPI_Request request)
    -> typename std::enable_if<!std::is_same<MPI_Request, int>::value, void>::type
{ 
    str(s, (void*)request); 
}
Run Code Online (Sandbox Code Playgroud)

之所以失败,MPI_Request是因为when 与相同int,该语句始终为false,并且由于它不依赖于任何模板参数,因此编译器完全拒绝对其进行编译。

我该如何解决这个问题,并append在队伍MPI_Request不同于int

Qui*_*mby 2

那真不幸。最重要的是,它enable_if只能在需要 T 模板的 SFINAE 上下文中使用。为了迭代您的想法,我们可以在返回类型中指定我们的要求,以便模板仅MPI_RequestMPI_Request类型不是int.

#include <string>
#include <type_traits>
using MPI_Request = int;// Or something else

template<typename T>
using T_is_MPI_and_not_also_int = std::conjunction<std::is_same<T,MPI_Request>, std::negation<std::is_same<MPI_Request,int>>>;

template<typename T>
std::enable_if_t<T_is_MPI_and_not_also_int<T>::value,void> 
append(std::string& s, T request);
Run Code Online (Sandbox Code Playgroud)

完整的示例,您甚至可以看到哪一cout行被内联到 main 中。