我有一个大型的第 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++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;
}