在模板化 class 的模板方法中重载 std::function 参数
Overloading a std::function parameter in templated method in templated class
我在 class 模板专业化中为模板化方法制作专用模板时遇到问题。
假设我有以下代码:
#include <functional>
template<typename T>
class myClass {
public:
T bar() {
return T();
}
template<typename P>
bool foo(std::function<P(T)> g) {
g(bar());
return true;
}
};
如果我想为 myClass<void>
专门化函数 bar
,我会这样做:
template<> void myClass<void>::bar() {
}
但是当我尝试以同样的方式专门化 foo
时,我得到一个编译器错误,指出 error: invalid parameter type ‘void’
并指向 foo.
的原始定义
template<>
template<typename P>
bool myClass<void>::foo(std::function<P(void)> g) {
bar();
g();
return true;
}
有没有人有什么建议,我做错了什么?
不完全是专业化...当 T
不是 void
时,您可以使用 SFINAE (std::enable_if
) 激活您的 foo()
版本并激活另一个版本foo()
当 T
是 void
.
以下是一个完整的工作示例
#include <iostream>
#include <functional>
template <typename T>
class myClass
{
public:
T bar()
{ return {}; }
template <typename P, typename U = T>
typename std::enable_if<false == std::is_same<U, void>::value,
bool>::type foo (std::function<P(U)> const & g)
{ g(bar()); return true; }
template <typename P, typename U = T>
typename std::enable_if<true == std::is_same<U, void>::value,
bool>::type foo (std::function<P()> const & g)
{ bar(); g(); return false; }
};
template<>
void myClass<void>::bar ()
{ }
int main()
{
myClass<int> mci;
myClass<void> mcv;
std::function<long(int)> fli { [](int i){ return long(i); } };
std::function<short()> fsv { [](){ return 0; } };
std::cout << mci.foo(fli) << std::endl; // print 1
std::cout << mcv.foo(fsv) << std::endl; // print 0
}
我在 class 模板专业化中为模板化方法制作专用模板时遇到问题。
假设我有以下代码:
#include <functional>
template<typename T>
class myClass {
public:
T bar() {
return T();
}
template<typename P>
bool foo(std::function<P(T)> g) {
g(bar());
return true;
}
};
如果我想为 myClass<void>
专门化函数 bar
,我会这样做:
template<> void myClass<void>::bar() {
}
但是当我尝试以同样的方式专门化 foo
时,我得到一个编译器错误,指出 error: invalid parameter type ‘void’
并指向 foo.
template<>
template<typename P>
bool myClass<void>::foo(std::function<P(void)> g) {
bar();
g();
return true;
}
有没有人有什么建议,我做错了什么?
不完全是专业化...当 T
不是 void
时,您可以使用 SFINAE (std::enable_if
) 激活您的 foo()
版本并激活另一个版本foo()
当 T
是 void
.
以下是一个完整的工作示例
#include <iostream>
#include <functional>
template <typename T>
class myClass
{
public:
T bar()
{ return {}; }
template <typename P, typename U = T>
typename std::enable_if<false == std::is_same<U, void>::value,
bool>::type foo (std::function<P(U)> const & g)
{ g(bar()); return true; }
template <typename P, typename U = T>
typename std::enable_if<true == std::is_same<U, void>::value,
bool>::type foo (std::function<P()> const & g)
{ bar(); g(); return false; }
};
template<>
void myClass<void>::bar ()
{ }
int main()
{
myClass<int> mci;
myClass<void> mcv;
std::function<long(int)> fli { [](int i){ return long(i); } };
std::function<short()> fsv { [](){ return 0; } };
std::cout << mci.foo(fli) << std::endl; // print 1
std::cout << mcv.foo(fsv) << std::endl; // print 0
}