c ++使用std :: enable_if有条件地将吸气剂添加到可变参数变体模板中

问题描述 投票:0回答:2

我正在尝试为我的变体以intfloatbool等中的任何一个作为模板参数的情况添加特殊化。

到目前为止,我的尝试是:

#include <iostream>
#include <variant>
#include <string>
#include <type_traits>

template<typename... Types>
struct variant : std::variant<Types...> {

    using std::variant<Types...>::variant;

    template<typename T>
    const T& get() const { return std::get<T>(*this); }

#define VARGET(X) typename std::enable_if<(std::is_same<Types, X>::value ||  ... ), X>::type get_##X() const { return get<X>(); }

    VARGET(int)
    VARGET(float)
    VARGET(double)
    VARGET(bool)
    using std_string = std::string;
    VARGET(std_string)
};

int main()
{

    variant<int, float, bool> var = 3;
    std::cout << var.get_int() << std::endl;

    variant<int, float, bool> var2 = 0.1f;
    std::cout << var2.get_float() << std::endl;

    return 0;
}

但是在gcc 9上会出现错误:

error: failed requirement 'std::is_same<int, double>::value || std::is_same<float, double>::value || std::is_same<bool, double>::value'; 'enable_if' cannot be used to disable this declaration

为什么让我感到困惑

根据我对SFINAE的理解,当参数之一为指定的类型之一时,宏模板的计算结果为:(以int为例)

[std::enable_if<(std::is_same<Types, int>::value || ... ), int>::type等于int

所以表达式变为int get_int() const { std::get<int>(*this) }

如果不是指定类型之一:

std::enable_if<(std::is_same<Types, size_t>::value || ... ), size_t>::type评估为无]

所以表达式变为get_size_t() const { std::get<size_t>(*this) }

这是无效的语法,因为该函数没有返回类型,但是由于SFINAE的原因,由于X的其他替换确实会产生有效的语法,因此它仍应编译。

我的代码有什么问题,有没有办法得到我想要的结果?

谢谢。

我正在尝试为变体以int,float,bool等为模板参数的情况添加特殊化。到目前为止,我的尝试是:#include #include

c++ c++17 template-meta-programming sfinae
2个回答
0
投票

我想出了答案。


0
投票

我在尝试编译代码时收到的错误与您的错误不同,请参见Compiler Explorer;我收到了预期的错误“ no type named type in ...”,因为SFINAE在这种情况下不适用。

© www.soinside.com 2019 - 2024. All rights reserved.