【发布时间】:2017-01-27 22:31:29
【问题描述】:
过去几个小时我一直在努力解决一个非常奇怪的问题(在解决了 SFINAE 的 5-6 个其他问题后,因为我是新手)。基本上在下面的代码中,我想让f() 为所有可能的模板实例化工作,但只有在N == 2 时才有g():
#include <type_traits>
#include <iostream>
template<typename T, int N>
class A
{
public:
void f(void);
void g(void);
};
template<typename T, int N>
inline void A<T, N>::f()
{
std::cout << "f()\n";
}
template<typename T, int N, typename std::enable_if<N == 2, void>::type* = nullptr>
inline void A<T, N>::g()
{
std::cout << "g()\n";
}
int main(int argc, char *argv[])
{
A<float, 2> obj;
obj.f();
obj.g();
return 0;
}
当我尝试编译它时,我得到一个关于有 3 个模板参数而不是两个的错误。然后,经过一些试验,我决定将g() 的定义移到A 本身的定义中,如下所示:
#include <type_traits>
#include <iostream>
template<typename T, int N>
class A
{
public:
void f(void);
template<typename t = T, int n = N, typename std::enable_if<N == 2, void>::type* = nullptr>
void g()
{
std::cout << "g()\n";
}
};
template<typename T, int N>
inline void A<T, N>::f()
{
std::cout << "f()\n";
}
int main(int argc, char *argv[])
{
A<float, 2> obj;
obj.f();
obj.g();
return 0;
}
现在,神奇地一切正常。但我的问题是为什么?编译器没有看到在类定义中我试图内联一个也依赖于 3 个模板参数的成员函数吗?或者让我们颠倒一下这个问题:如果它在A 的定义中起作用,为什么它在外面不起作用?区别在哪里?不是还有3个参数,比A的模板参数需要哪个类多+1吗?
另外,为什么它只在我将第三个参数设为非类型而不是类型时才有效?请注意,我实际上创建了一个由 enable_if 返回的类型的指针,并为其分配了一个默认值 nullptr,但我看到我不能像在我在这里看到的其他 SO 论坛帖子中那样将它作为类型参数留在那里。
非常感谢,谢谢!!!
【问题讨论】:
标签: c++ templates sfinae enable-if partial-specialization