SFINAE可以检测到私人访问违规吗?

Joh*_*itb 15 c++ sfinae language-lawyer

我想知道如果我测试一个班级的某个成员并且该成员是私人的,那么sfinae会做出什么反应?它是否会出错或者说是好的还是会以错误的方式出错?

Mat*_* M. 11

是.

编辑: C++ 11标准引自§14.8.2[temp.deduct]

8 /如果替换导致无效的类型或表达式,则类型推导失败.如果使用替换参数写入,则无效的类型或表达式将是格式错误的.[注意:访问检查是作为替换过程的一部分完成的. - 尾注]

这表明我private可以触发SFINAE错误.阅读:

只有函数类型的直接上下文中的无效类型和表达式及其模板参数类型才会导致演绎失败.[注意:对替换类型和表达式的评估可能会导致副作用,例如类模板特化和/或函数模板特化的实例化,隐式定义函数的生成等.这些副作用不在"立即上下文"并且可能导致程序格式不正确.-最后说明]

"直接背景"对我来说并不是那么清楚......但它与我的观点并不矛盾:)

编辑结束

所以在我看来它会以SFINAE的方式出错,这一点从Clang的这段摘录中得到进一步证实:

// clang/Basic/DiagnosticIDs.h:185-209

  /// \brief Enumeration describing how the the emission of a diagnostic should
  /// be treated when it occurs during C++ template argument deduction.
  enum SFINAEResponse {
    /// \brief The diagnostic should not be reported, but it should cause
    /// template argument deduction to fail.
    ///
    /// The vast majority of errors that occur during template argument
    /// deduction fall into this category.
    SFINAE_SubstitutionFailure,

    /// \brief The diagnostic should be suppressed entirely.
    ///
    /// Warnings generally fall into this category.
    SFINAE_Suppress,

    /// \brief The diagnostic should be reported.
    ///
    /// The diagnostic should be reported. Various fatal errors (e.g.,
    /// template instantiation depth exceeded) fall into this category.
    SFINAE_Report,

    /// \brief The diagnostic is an access-control diagnostic, which will be
    /// substitution failures in some contexts and reported in others.
    SFINAE_AccessControl
  };
Run Code Online (Sandbox Code Playgroud)

在SFINAE的情况下,存在关于访问控制的特殊情况.


Pla*_*aHH 5

不,我在旅途中并没有引用标准的标准,但是在编译阶段,编译器会检查名称是否存在,并且在稍后阶段进行访问控制.

这类似于重载决策,其中考虑了所有名称,并且私有匹配更好,但不会编译,尽管有另一个匹配"ok"但不是私有.

加成:

核心问题1170说:

1170模板参数扣除期间的访问检查
部分:14.8.2 [temp.deduct]
状态:FDIS提交者:Adamczyk日期:2010-08-03

[2011年3月会议上投票支持WP.]

根据14.8.2 [temp.deduct]第8段,

访问检查不是替换过程的一部分.因此,当推导成功时,在实例化函数时仍可能导致访问错误.

这模仿了在重载决策中完成访问检查的方式.但是,经验表明,从扣减失败中获取访问错误会使标准库大大复杂化,因此应更改此规则.

拟议决议(2011年1月):

更改14.8.2 [temp.deduct]第8段如下:

如果替换导致无效的类型或表达式,则类型推导失败.如果使用替换参数写入,则无效的类型或表达式将是格式错误的.[注意:访问检查不是替换过程的一部分.-end note]因此,当演绎成功时,在实例化函数时仍可能导致访问错误.只有无效的类型......

所以我的解释是在C++ 03中这是不可能的,但是C++ 11使它成为可能.