繁体   English   中英

使用std :: get的SFINAE constexpr

[英]SFINAE constexpr with std::get

这是使用SFINAE检测constexpr的后续问题。

我想检测一个元组的元素(或可以与std::get一起使用的任何元素)是否为constexpr。 因此,我写了以下类似于Xeo提供的帮助程序:

template<size_t> struct sfinae_true : std::true_type{};

template<size_t N, class T>
auto check(const T& arg) -> sfinae_true<(std::get<N>(arg),N)>;

template<size_t N, class>
std::false_type check(...);

现在我的测试驱动程序代码:

int main()
{
    constexpr std::tuple<size_t, size_t> arg(4,5);
    typedef decltype(check<0,decltype(arg)>(arg)) is_cexpr;
    std::cout << "is constexpr? " << is_cexpr::value << '\n';
}

但是,这总是为我打印出false的! 为了检查由于某种原因而并非总是调用虚假重载,我注释掉了虚假重载并获取编译器错误:

注意:候选模板被忽略:替换失败[N = 0,T = const std :: tuple]:非类型模板参数不是常量表达式
自动检查(const T&arg)-> sfinae_true <(std :: get(arg),0)>;

但是,我知道我可以调用std::get<N>(arg)并获取constexpr值:

template<size_t N>
class A{};

int main()
{
    constexpr std::tuple<size_t, size_t> arg(4,5);
    A<std::get<0>(arg)> a_val;
}

这样编译就可以了。

  • 为什么检查功能不能正确检测到构造性?
  • 我该如何解决?

我在Ubuntu 16.04上使用Clang 3.8.0进行了测试。

编辑:

作为基于Sam答案的进一步测试,我尝试了以下形式:

template<size_t N, class T>
auto check(const T& arg)
{
    return sfinae_true<(std::get<N>(arg)*0)>();
}

这完全摆脱了逗号运算符,GCC 5.4.0可以很好地编译它,但是Clang 3.8.0仍然抱怨。 有趣的是,Clang强调arg本身不是constexpr。

为什么仍然有问题? constexpr函数参数的规则是什么?

这看起来像是编译器问题。

template<size_t N, class T>
auto check(const T& arg) -> sfinae_true<(std::get<N>(arg),N)>;

gcc无法编译此代码:

tC:8:61:错误:模板参数1无效自动检查(const T&arg)-> sfinae_true <(std :: get(arg),N)>;

但是在稍作调整之后,我在gcc 6.1.1中获得了预期的结果:

#include <tuple>
#include <type_traits>
#include <iostream>

template<size_t> struct sfinae_true : std::true_type{};

template<size_t N, class T>
auto check(const T& arg)
{
    return sfinae_true<(std::get<N>(arg),N)>();
}

template<size_t N, class>
std::false_type check(...);

int main()
{
    constexpr std::tuple<size_t, size_t> arg(4,5);
    typedef decltype(check<0,decltype(arg)>(arg)) is_cexpr;
    std::cout << "is constexpr? " << is_cexpr::value << '\n';
}

结果是:

is constexpr? 1

请注意,C ++ 11之前的常量表达式中不允许使用逗号。 可能是那个时代遗留下来的东西...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM