Multiple SFINAE class template specialisations using void_t

后端 未结 2 1442
-上瘾入骨i
-上瘾入骨i 2020-12-10 10:45

Are multiple class template specialisations valid, when each is distinct only between patterns involving template parameters in non-deduced contexts?

A common exampl

2条回答
  •  清歌不尽
    2020-12-10 11:40

    I don't believe it's correct, or at least, not if we instantiate has_members with a type that has both type1 and type2 nested, the result would be two specializations that are

    has_members 
    

    which would not be valid. Until the code is instantiated I think it's ok, but clang is rejecting it early. On g++, your fails with this use-case, once instantiated:

    struct X
    {
        using type1 = int;
        using type2 = double;
    };
    
    int main() {
        has_members::value;
    }
    

    The error message is doesn't seem to describe the actual problem, but it at least is emitted:

    :20:21: error: incomplete type 'has_members' used in nested name specifier
         has_members::value;
                         ^~~~~
    

    If you instantiate it with a type that has only type1 or type2 but not both, then g++ compiles it cleanly. So it's objecting to the fact that the members are both present, causing conflicting instantiations of the template.

    To get the disjunction, I think you'd want code like this:

    template >
    struct has_members : std::bool_constant {};
    
    template 
    struct has_members, has_member_type2>::value>> : 
        std::bool_constant {};
    

    This assumes you have traits to determine has_member_type1 and has_member_type2 already written.

提交回复
热议问题