std::enable_if 使用其内部类型和不使用它
std::enable_if using its internal type and without using it
为什么会打印"B"
#include <iostream>
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, typename std::enable_if<true>::type>
{ static void apply() { std::cout << "B" << std::endl; } };
int main()
{
Test<int>::apply();
}
但是这个 "A"?:
#include <iostream>
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, std::enable_if<true>>
{ static void apply() { std::cout << "B" << std::endl; } };
int main()
{
Test<int>::apply();
}
它们之间的唯一区别是,在第一个中,我将 typename std::enable_it<true>::type
用作 U
(例如,void
),但在第二个中,我我直接将 std::enable_if<true>
用作 U
,这也是一个定义明确的类型,没有更多的含义,如 void
。
由于 typename std::enable_if<true>::type
与 void
的类型相同,因此第一个片段相当于
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, void> // since typename std::enable_if<true>::type == void
{ static void apply() { std::cout << "B" << std::endl; } };
因此,第二个定义更专业,因此如果您不提供两个模板参数,则后者在重载决策中获胜。
然而,在第二个例子中,你只是对 T
和 std::enable_if<true>
这对类型的特化,而不是 T
和 void
的特化。
这可以用 std::is_same<std::enable_if<true>, void>
来检查,它的计算结果为 false(显然,void
没有类型成员 type
,所以它不可能相同)。
因此,对于第二个片段,请求 T<int>
将与 T<int, void>
匹配,其中只有一个定义相关,即第一个。
因为当你写 Test<int>
时,你实际上写的是 Test<int, void>
,它永远不会与 Test<int, std::enable_if<true>>
相同(尽管它与 Test<int, typename std::enable_if<true>::type>
相同)
为什么会打印"B"
#include <iostream>
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, typename std::enable_if<true>::type>
{ static void apply() { std::cout << "B" << std::endl; } };
int main()
{
Test<int>::apply();
}
但是这个 "A"?:
#include <iostream>
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, std::enable_if<true>>
{ static void apply() { std::cout << "B" << std::endl; } };
int main()
{
Test<int>::apply();
}
它们之间的唯一区别是,在第一个中,我将 typename std::enable_it<true>::type
用作 U
(例如,void
),但在第二个中,我我直接将 std::enable_if<true>
用作 U
,这也是一个定义明确的类型,没有更多的含义,如 void
。
由于 typename std::enable_if<true>::type
与 void
的类型相同,因此第一个片段相当于
template<typename T, typename U = void>
struct Test
{ static void apply() { std::cout << "A" << std::endl; } };
template<typename T>
struct Test<T, void> // since typename std::enable_if<true>::type == void
{ static void apply() { std::cout << "B" << std::endl; } };
因此,第二个定义更专业,因此如果您不提供两个模板参数,则后者在重载决策中获胜。
然而,在第二个例子中,你只是对 T
和 std::enable_if<true>
这对类型的特化,而不是 T
和 void
的特化。
这可以用 std::is_same<std::enable_if<true>, void>
来检查,它的计算结果为 false(显然,void
没有类型成员 type
,所以它不可能相同)。
因此,对于第二个片段,请求 T<int>
将与 T<int, void>
匹配,其中只有一个定义相关,即第一个。
因为当你写 Test<int>
时,你实际上写的是 Test<int, void>
,它永远不会与 Test<int, std::enable_if<true>>
相同(尽管它与 Test<int, typename std::enable_if<true>::type>
相同)