c++ - SFINAE enable_if 启用 c++11 之前的构造函数

标签 c++ templates sfinae clang++

我的构造函数有两个不同版本(一个用于 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/

相关文章:

c++ - 我可以在控制流语句中使用 SFINAE 测试吗?

c++ - SFINAE:如果不带参数调用,则会出现不明确的重载

c++ - 在 Qt 信号/槽的上下文中使用观察者模式

c++ - 为另一个类专门化模板类的运算符<<

c++ - 使用SFINAE计算不同元素的大小

c++ - 一个简单类模板的c++17中的 friend 流运算符

c++ - 为什么选择 "universal reference"重载而不是 char 数组或 char 指针?

c++ - 我应该使用 boost 快速池分配器进行跟踪吗?

c++ - 如何让派生类调用其他派生类的方法?面向对象设计

C++ 交互式命令行提示符,无需等待换行符