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?
那真不幸。最重要的是,它enable_if只能在需要 T 模板的 SFINAE 上下文中使用。为了迭代您的想法,我们可以在返回类型中指定我们的要求,以便模板仅MPI_Request在MPI_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 中。