【问题标题】:enable_if works with gcc but not with clang and msvcenable_if 适用于 gcc 但不适用于 clang 和 msvc
【发布时间】:2022-11-26 05:36:34
【问题描述】:

我了解了 SFINAE 原理及其各种用途。然后我写了下面的程序,用 gcc 编译但不用 msvc 和 clang。 Live demo。

#include <iostream>
#include <type_traits>

template <typename T> class Container {
    public:

        template<typename U = T> 
        std::enable_if_t<std::is_same_v<T, int>> foo(const T&)
        {

        }
};

template<typename T>
void func(T&& callable)
{
    Container<int> c;
    (c.*callable)(4);
}
int main(){

    //works with gcc but not with clang and msvc
    func(&Container<int>::foo); 
} 

正如我们所看到的,上面的程序适用于 gcc,但不适用于 clang 和 msvc,我不知道哪个编译器就在这里。那么这个程序是良构的还是病态的等等。

【问题讨论】:

  • 问题不在于enable_if。将其更改为void,您应该会得到相同的错误。
  • 凉爽的。如果在指向 foo 的指针处显式特化 foo&lt;int&gt;,则工作正常。此外,它要么在不使用时自动“跳过”成员函数,因此您不需要禁用它们,要么有多个这样的函数,并且每次“获取指针”时都禁用除一个之外的所有函数,但是那么在获取指向它的指针时,您仍然需要以某种方式消除您对哪个函数感兴趣的歧义。你有用例吗?
  • 由于CWG 2608,该程序格式正确。
  • 顺便说一句,你的enable_if用法是错误的:实例化Container&lt;char&gt;会产生硬错误,你需要std::enable_if_t&lt;std::is_same_v&lt;U, int&gt;&gt;。在 C++20 中,requires(std::is_same_v&lt;T, int&gt;)(并删除模板)会简化事情。

标签: c++ language-lawyer


【解决方案1】:

这是CWG 2608,程序是良构的.

如果可以推导出所有模板参数或者从默认的模板参数中获取,它们都可以被省略;在这种情况下,空模板参数列表 <> 本身也可以省略。

(强调我的)

请注意使func(&amp;Container&lt;int&gt;::foo);格式正确的添加部分因为 U 的模板参数可以从默认模板参数中获得,因此它可以被省略,这意味着空模板参数列表 &lt;&gt; 本身也可以被省略.因此,gcc 符合标准。

这是 clang 错误:

Clang rejects valid program with default argument

这是 msvc 错误:

MSVC rejects valid program with default argument

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 2022-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多