SFINAE 根据类值模板参数选择构造函数 [英] SFINAE to select constructor based on class value template parameter

查看:54
本文介绍了SFINAE 根据类值模板参数选择构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个类,该类根据类自己的模板参数的值公开不同的构造函数.想到尝试这样做的幼稚代码如下:

I'm trying to write a class that exposes different constructors depending on the value of the class's own template parameters. The naive code that came to mind trying to do this is as follows :

// C++14
#include <type_traits>

template <int compile_time_w = -1, int compile_time_h = -1>
struct Grid
{
    template <std::enable_if_t<compile_time_w < 0 && compile_time_h < 0, int> = 0>
    Grid(int runtime_w, int runtime_h) : _w(runtime_w), _h(runtime_h) {}

    template <std::enable_if_t<compile_time_w < 0 && compile_time_h >= 0, int> = 0>
    Grid(int runtime_w) : _w(runtime_w), _h(compile_time_h) {}

    template <std::enable_if_t<compile_time_w >= 0 && compile_time_h < 0, int> = 0>
    Grid(int runtime_h) : _w(compile_time_w), _h(runtime_h) {}

    template <std::enable_if_t<compile_time_w >= 0 && compile_time_h >= 0, int> = 0>
    Grid() : _w(compile_time_w), _h(compile_time_h) {}

    int _w, _h;
};

int main()
{
    // Grid<2, 2> grid; // any combination of template parameters + constructor parameters fails to compile

    return 0;
}

在没有任何实例化的情况下编译类工作正常,但尝试以任何方式或容量实例化它总是失败.编译错误总是相同的格式,并且为每个 SFINAE 应该触发的构造函数报告:

Compiling the class without any instantiation of it works fine, but trying to instantiate it in any way or capacity always fails. The compilation error is always of the same format, and is reported for every constructor where SFINAE should trigger :

错误:struct std::enable_if"中没有名为type"的类型

显然 std::enable_if 正在按预期工作,但不知何故不应被视为错误.关于这一切的任何线索?

Apparently std::enable_if is working as intended, but somehow what should not be considered as an error is. Any clue on what this is all about ?

推荐答案

为了使用 SFINAE,模板参数必须是当前模板的一部分.由于 compile_time_wcompile_time_h 是类模板参数的一部分,因此它们不可用.要修复它,请将它们添加到每个函数模板中,例如

In order to use SFINAE, the template parameters must be part of the current template. Since compile_time_w and compile_time_h are part of the class's template parameters, they are not usable. To fix it add them to each function template like

template <int compile_time_w = -1, int compile_time_h = -1>
struct Grid
{
    template <int compile_time_w_l = compile_time_w, int compile_time_h_l = compile_time_h, std::enable_if_t<compile_time_w_l < 0 && compile_time_w_l < 0, int> = 0>
    Grid(int runtime_w, int runtime_h) : _w(runtime_w), _h(runtime_h) {}

    template <int compile_time_w_l = compile_time_w, int compile_time_h_l = compile_time_h, std::enable_if_t<compile_time_w_l < 0 && compile_time_w_l >= 0, int> = 0>
    Grid(int runtime_w) : _w(runtime_w), _h(compile_time_h) {}

    template <int compile_time_w_l = compile_time_w, int compile_time_h_l = compile_time_h, std::enable_if_t<compile_time_w_l >= 0 && compile_time_w_l < 0, int> = 0>
    Grid(int runtime_h) : _w(compile_time_w), _h(runtime_h) {}

    template <int compile_time_w_l = compile_time_w, int compile_time_h_l = compile_time_h, std::enable_if_t<compile_time_w_l >= 0 && compile_time_w_l >= 0, int> = 0>
    Grid() : _w(compile_time_w), _h(compile_time_h) {}

    int _w, _h;
};

int main()
{
    Grid<2, 2> grid; // any combination of template parameters + constructor parameters fails to compile

    return 0;
}

这篇关于SFINAE 根据类值模板参数选择构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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