我的构造函数有两个不同版本(一个用于 GPU,一个用于 CPU),但这两个版本的类的其余部分几乎相同。
我想通过 SFINAE enable_if 语句启用此类的 cpu 变体。
问题是,我需要在没有 C++11 的情况下使用 clang++ 来编译它。
下面的代码可以正常工作,但它会生成五个警告:
warning: default template arguments for a function template are a C++11
extension [-Wc++11-extensions]
有没有办法使用 sfinae 而不需要使用标准 C++11 编译 C++ 代码,并且没有 c++11 警告?
这是代码:
#include <iostream>
enum arch_t{cpu, gpu};
template<bool B, class T=void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
template<typename T1, arch_t arch>
class data {
public:
template<arch_t a=arch, typename enable = typename enable_if<a==cpu, void>::type, typename tmp = enable>
data(void)
{
std::cout << "-CPU()" << std::endl;
}
template<arch_t a=arch, typename = typename enable_if<a!=cpu, void>::type>
data(void)
{
std::cout << "-GPU()" << std::endl;
}
};
int main()
{
data<int,gpu> gpu_data;
data<int,cpu> cpu_data;
}
预期(也是实际)输出: -GPU() -CPU()
我使用 clang++-3.8 进行编译。
最佳答案
建议将此作为替代解决方案。
我们可以使用标签来代替 SFINAE。这里,标签是一个空结构,其名称充当一条信息(标签)。然后我们可以使用标签重载函数(包括构造函数),因为它是一种类型。所以在这种情况下我们可以有类似的东西
struct cpu_arch_t {} cpu_arch;
struct gpu_arch_t {} gpu_arch;
template<typename T1>
class data {
public:
data(cpu_arch_t)
{
std::cout << "-CPU()" << std::endl;
}
data(gpu_arch_t)
{
std::cout << "-GPU()" << std::endl;
}
};
然后我们就可以像这样使用它
int main()
{
data<int> gpu_data(gpu_arch);
data<int> cpu_data(cpu_arch);
}
关于c++ - SFINAE enable_if 启用 c++11 之前的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44334565/