相关疑难解决方法(0)

模板偏序 - 为什么部分演绎在这里成功

考虑以下简单(在模板问题的范围内)示例:

#include <iostream>

template <typename T>
struct identity;

template <>
struct identity<int> {
    using type = int;
};

template<typename T> void bar(T, T ) { std::cout << "a\n"; }
template<typename T> void bar(T, typename identity<T>::type) { std::cout << "b\n"; }

int main ()
{
    bar(0, 0);
}
Run Code Online (Sandbox Code Playgroud)

clang和gcc都在那里打印"a".根据[temp.deduct.partial]和[temp.func.order]中的规则,为了确定部分排序,我们需要合成一些独特的类型.所以我们有两次尝试扣除:

+---+-------------------------------+-------------------------------------------+
|   | Parameters                    | Arguments                                 |
+---+-------------------------------+-------------------------------------------+
| a | T, typename identity<T>::type | UniqueA, UniqueA                          |
| b | T, T                          | UniqueB, typename identity<UniqueB>::type |
+---+-------------------------------+-------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

根据Richard Corden的回答 …

c++ templates partial-ordering language-lawyer overload-resolution

20
推荐指数
2
解决办法
1166
查看次数

带有SFINAE伪参数的模糊模板

考虑一种情况,需要在T另一个模板的虚拟参数内验证具有另一个模板的类型g(enable_if例如,可能是某个表达式),如下所示:

template<class>        struct g { typedef void type; };
template<class, class> struct f {};
template<class T>      struct f<T, void> {};                  // Case A
template<class T>      struct f<T*, typename g<T>::type> {};  // Case B

int main() { f<int*, void> test; }
Run Code Online (Sandbox Code Playgroud)

在这里,为了简单起见,g并没有真正做任何事情.案例B中的第二个参数位于非弱化上下文中,因此直观地认为案例B案例A更专业.可悲的是,gcc和clang都会抱怨模板在上面的实例化中是模棱两可的.

如果要删除虚拟参数,那么它编译就好了.如何添加一个非弱化参数会以某种方式破坏T*比这更专业的合理期望T

这是使用替换算法的快速检查:

   f<Q , void      >
-> f<T*, g<Q>::type> // [failed]

   f<Q*, g<Q>::type>
-> f<T , void      > // [to fail …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae template-specialization template-meta-programming

7
推荐指数
1
解决办法
583
查看次数