首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >中国建筑工程师协会在VC2017中工作,但没有在clang/gcc中工作

中国建筑工程师协会在VC2017中工作,但没有在clang/gcc中工作
EN

Stack Overflow用户
提问于 2017-10-06 10:10:39
回答 2查看 482关注 0票数 5
代码语言:javascript
复制
#include <type_traits>

template<bool b>
struct S
{
    template<typename = std::enable_if_t<b>>
        S() {}
    template<typename = std::enable_if_t<!b>>
        S(int) {}
};

S<true> s{}; // error in clang/gcc, OK in VC2017
S<false> s{0}; // error in clang/gcc, OK in VC2017

在这两种情况下,clang/gcc都试图实例化由于SFINAE而应该丢弃的ctor。错误信息是:

错误:在'std::enable_if< false,void>‘中没有一个名为“enable_if”的类型不能用于禁用此声明

clang/gcc对另一个ctor的实例化是不正确的,因为它应该而不是在可能的重载列表中,对吗?

但是在我提交一个bug之前,我想看看其他人的想法。也许我搞错了.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-06 10:50:56

这是MSVC中的一个bug,clang和gcc是对的。

问题是SFINAE只发生在过载分解过程中,而不是以前。我的意思是,如果这个函数在你调用它之前是不正确的,那就是一个错误。

例如,当您使用S<true>时,将实例化整个类。它看起来有点像这样:

代码语言:javascript
复制
struct S_true
{
    template<typename = void>
    S() {}

    template<typename = /*fail*/>
    S(int) {}
};

正如您所看到的,第二个构造函数的格式完全错误,它不是一个有效的定义,因为没有找到类型type (因为std::enable_if)。因此,SFINAE甚至不能发挥作用,类定义是错误的和诊断的。

您需要将模板参数b作为两个构造函数的模板参数列表的一部分(请查看@bolov的答案)。

票数 11
EN

Stack Overflow用户

发布于 2017-10-06 11:41:24

@ right 1111是100%正确的。

您需要将模板参数bool作为两个构造函数的模板参数列表的一部分。

下面是如何做到这一点(这是一种非常标准的技术):

代码语言:javascript
复制
template<bool b>
struct S
{
    template<bool bb = b, typename = std::enable_if_t<bb>>
        S() {}
    template<bool bb = b, typename = std::enable_if_t<!bb>>
        S(int) {}
};
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46603353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档