这个问题可能太难在标题中的on句子中描述,但这里有一个最小的例子:
#include <iostream>
#include <type_traits>
template <class T, class U, class Enabler>
struct my_trait : std::false_type
{};
template <class T, class U>
struct my_trait<T, U,
std::enable_if_t<std::is_same<T, U>::value>> : std::true_type
{};
template <class T>
class temped
{};
template <class T>
struct my_trait<temped<T>, temped<T>, void> : std::false_type
{};
template <class T, class U>
using trait_t = my_trait<T, U, void>;
int main()
{
std::cout << std::boolalpha;
std::cout << trait_t<int, float>::value << std::endl; // false
std::cout << trait_t<int, int>::value << std::endl; // true
// Compilation error: Ambiguous
//std::cout << trait_t<temped<int>, temped<int>>::value << std::endl;
return 0;
}
temped
类模板的实例化时天真地说,我们希望第二个部分专门化不会与第一个不明确,因为它感觉“更专门化”,对基础模板上T
和U
的推导类型施加更多限制。然而,主要的编译器似乎同意我们的期望是错误的:为什么它不被认为是更专业化的?
@超级现在被删除的答案基本上是对的。std::enable_if_t<...>
在偏序中不是void
;作为依赖类型,它原则上可以是完全任意的。对于偏序的目的,它有效地被认为是一个完全唯一的类型。
由于这种不匹配,偏序期间的推导在两个方向上都失败,并且专门化是不明确的。
还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案
但是指定它是,因此它不再是模板类。它是否可以像虚函数一样专门化或重写?
我有几个模板参数的模板结构 此结构适用于所有模板,但结果无效的情况除外。我知道,不能实现为void类型,所以我当前的解决方案是使用如下的部分专门化: 这允许执行以下操作: 有没有一种方法可以使编译而不会在C 14标准中进行部分类特化?我可以使用和类型trait组合,但我想找到是否有一种方法: > 模板类方法的特殊化部分显式 模板类方法的实例化
让我们考虑以下代码: 我知道第二个声明是重载,而不是部分专业化: 但我想知道它与部分专业化有何不同?它为我们提供了与部分专业化相同的功能,不是吗?
请向我解释选择模板专用化的规则。我举一个例子: 为什么输出为?一般来说,专用类中的默认模板参数会发生什么情况?它会带来一些影响吗?