Vio*_*ffe 16 c++ sfinae type-traits c++17
decay_t我需要一个类型特征,将枚举衰减为其基础类型,并且与所有其他类型的工作方式相同。我编写了以下代码,显然这不是 SFINAE 的工作方式。但这就是我认为它应该工作的方式,那么这段代码到底有什么问题以及我对 C++ 的理解有何差距?
namespace detail {
template <typename T, std::enable_if_t<!std::is_enum_v<T>>* = nullptr>
struct BaseType {
using Type = std::decay_t<T>;
};
template <typename T, std::enable_if_t<std::is_enum_v<T>>* = nullptr>
struct BaseType {
using Type = std::underlying_type_t<T>;
};
}
template <class T>
using base_type_t = typename detail::BaseType<T>::Type;
Run Code Online (Sandbox Code Playgroud)
MSVC中的错误完全无法理解:
“detail::BaseType”:模板参数“__formal”与声明不兼容
在 GCC 中,情况要好一些 - 表示第二个模板参数的声明在两个BaseType模板之间不兼容。但根据我对 SFINAE 的理解,对于任何给定的 T 来说,只有一个应该可见,而另一个应该由于enable_if.
Sto*_*ica 19
应用于类模板的 SFINAE 主要是在模板的部分特化之间进行选择。您的代码片段中的问题是看不到部分专业化。您定义两个具有相同模板名称的主类模板。这是一个重新定义错误。
为了使其发挥作用,我们应该重新构建特征实现之间的关系,例如它们专门化相同的模板。
namespace detail {
template <typename T, typename = void> // Non specialised case
struct BaseType {
using Type = std::decay_t<T>;
};
template <typename T>
struct BaseType<T, std::enable_if_t<std::is_enum_v<T>>> {
using Type = std::underlying_type_t<T>;
};
}
template <class T>
using base_type_t = typename detail::BaseType<T>::Type;
Run Code Online (Sandbox Code Playgroud)
专业化void为第二个参数提供了类型(就像实例化主参数一样)。但由于它以“特殊方式”进行,因此部分排序认为它更专业。当替换失败时(我们不传递枚举),主数据库将成为后备数据库。
您可以根据需要提供任意数量的此类专业化,只要第二个模板参数始终为void,并且所有专业化都具有互斥条件。
康桓瑋*_*康桓瑋 11
BaseType不是部分专业化,您只是重新声明它,并且由于非类型参数具有不同的类型,因此编译失败。你可能想做
#include <type_traits>
namespace detail {
template <typename T, bool = std::is_enum_v<T>>
struct BaseType;
template <typename T>
struct BaseType<T, false> {
using Type = std::decay_t<T>;
};
template <typename T>
struct BaseType<T, true> {
using Type = std::underlying_type_t<T>;
};
}
Run Code Online (Sandbox Code Playgroud)
您使用不同的参数声明相同的结构,这是禁止的。
您可以通过部分专业化来做到这一点:
namespace detail {
template <typename T, typename Enabler = void>
struct BaseType {
using Type = std::decay_t<T>;
};
template <typename E>
struct BaseType<E, std::enable_if_t<std::is_enum_v<E>>>
{
using Type = std::underlying_type_t<E>;
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1367 次 |
| 最近记录: |