不明确的部分专业化

问题描述 投票:0回答:1

我有一个大型的第 3 方库,我正在尝试使用最新的 clang(版本 19)进行编译,但我一直遇到

ambiguous partial specializations
错误。重现该问题的最小示例如下所示:

#include <type_traits>
#include <vector>

struct Type
{
    template <typename T>
    static Type get() { return {}; }
};

template<typename T>
struct template_type_trait : std::false_type
{
    static std::vector<Type> get_template_arguments() { return {}; }
};

template<template <typename... > class T, typename...Args>
struct template_type_trait<T<Args...>> : std::true_type
{
    static std::vector<Type> get_template_arguments() { return { Type::get<Args>()..., }; }
};

#define ADD_TYPE_TRAIT_SPECIALIZATION(value_type)                                                                                    \
    template<template <value_type> class T, value_type Arg>                                                                                 \
    struct template_type_trait<T<Arg>> : std::true_type                                                                                     \
    {                                                                                                                                       \
        static std::vector<Type> get_template_arguments() { return { Type::get<value_type>() }; }                           \
    };

ADD_TYPE_TRAIT_SPECIALIZATION(std::size_t)
ADD_TYPE_TRAIT_SPECIALIZATION(bool)
ADD_TYPE_TRAIT_SPECIALIZATION(int)
ADD_TYPE_TRAIT_SPECIALIZATION(char)

// //////////////////////////////////////////////////////////////
   
template <bool>
struct BB { };

int main()
{
    return template_type_trait<BB<true>>::value;
}

您还可以在这里找到一个实例:https://godbolt.org/z/hvc6zjj1q

在其他编译器 (MSVC) 和 clang 的早期版本中,这不是问题。为什么非类型专业化会不明确?这是编译器中的错误吗?看起来用

-fno-relaxed-template-template-args
编译成功了。对于更好的解决方法/修复有什么建议吗?

c++ templates clang
1个回答
0
投票

所以我找到了一种使用 C++17 的

template<auto>
来编译该代码的方法:

#include <type_traits>
#include <vector>

struct Type
{
    template <typename T>
    static Type get() { return {}; }
};

template<typename T>
struct template_type_trait : std::false_type
{
    static std::vector<Type> get_template_arguments() { return {}; }
};

template<template <typename... > class T, typename...Args>
struct template_type_trait<T<Args...>> : std::true_type
{
    static std::vector<Type> get_template_arguments() { return { Type::get<Args>()..., }; }
};

template<template <auto> class T, auto Arg>
struct template_type_trait<T<Arg>> : std::true_type
{                                                                                                                                       
        static std::vector<Type> get_template_arguments() { return { Type::get<decltype(Arg)>() }; }
};

// //////////////////////////////////////////////////////////////
   
template <bool>
struct BB { };

int main()
{
    return template_type_trait<BB<true>>::value;
}
© www.soinside.com 2019 - 2024. All rights reserved.