使用C ,使用SFINAE测试静态成员的存在,返回错误的值

Using C++, test existence of static member using SFINAE, return wrong value

本文关键字:使用 返回 错误 存在 静态成员 SFINAE 测试      更新时间:2023-10-16

我正在学习模板元图。尝试使用以下代码测试静态成员时,第二个Sfinae总是返回错误的值:

#include <cstdio>
#include <type_traits>
// ts_a
struct ts_a
{
    static int a;
};
// ts_b
struct ts_b
{
    static int b;
};
// has_a
template<typename T, typename = std::void_t<>>
struct has_a : std::false_type {};
template<typename T>
struct has_a<T, std::void_t<decltype( T::a )>> : std::true_type {};
// has_b
template<typename T, typename = std::void_t<>>
struct has_b : std::false_type {};
template<typename T>
struct has_b<T, std::void_t<decltype( T::b )>> : std::true_type {};
int main()
{
    printf( "%sn", has_a<ts_a>::value ? "true" : "false" );
    printf( "%sn", has_b<ts_a>::value ? "true" : "false" );
    printf( "%sn", has_a<ts_b>::value ? "true" : "false" );
    printf( "%sn", has_b<ts_b>::value ? "true" : "false" );  
    return 0;
}

我正在使用Microsoft(R)C/C 优化编译器版本19.15.26732.1 x64

true
true
false
false

但是,当使用GCC编译时,它返回预期值

true
false
false
true

当定义has_b之前的has_a(ctrl-xv has_b之前has_a之前)时,msvc返回

false
false
true
true

那么,这是编译器问题吗?

两个编译器上的以下替代作品,但也返回到非静态成员。有什么方法可以检测到真正的静态成员?

template <class T>                                                  
struct has_a_2
{                                           
    template<typename U>                        
    static std::true_type check( decltype( U::a )* );
    template<typename U>
    static std::false_type check(...);                          
public:                                                             
    static constexpr const bool value = decltype( check<T>( 0 ) )::value;
};

这是一个MSVC错误。

标题为:表达式Sfinae问题已提交的错误报告。

根据报告中提到的解决方案,此问题是固定的,并且可以在最新的预览Visual Studio 2019中使用。

这在GCC和Clang上都可以正常工作。