我有一个模板类
template <typename S>
class Foo {
template <typename T>
T Bar();
}
如何更改Bar
以便我可以在不更改类模板类型的情况下使用它?
Foo<int> f;
f.Bar<int,MyType>();
这里,int是Foo
的类型,MyType
只是在其实例类型之上更改Bar()
行为的另一种类型。
这不按预期工作:
template <typename S>
template <typename T>
T Foo<S>::Bar()
{
// logic with T t
}
但这有效:
template <typename S>
template <typename T>
T Foo<S>::Bar(T * dummyNullPointer)
{
// logic with T t
}
是否有一个整洁的版本而不是代码?
f.Bar<int>((float *)0);
最好
f.Bar<int,MyType>();
或
f.Bar<MyType>(); // better, but expects int for example and gives error
编辑:实际使用情况
void SomeClass<SomeType>::SomeMethod(SomeType1<SomeType> p)
{
Something something = p.SomeWork<Something>(); // does not work
}
答案 0 :(得分:1)
您不能专门化非专业类的成员函数。这只是一种语言限制。
如果您准备专攻课程,可以这样做:
#include <iostream>
#include <tuple>
template <typename S>
struct Foo {
template <typename T>
T Bar();
};
template <typename S>
template <typename T>
T Foo<S>::Bar()
{
std::cout << "usual thing" << std::endl;
return T();
}
struct MyType {};
template<> template<>
std::tuple<int, MyType> Foo<int>::Bar<std::tuple<int, MyType>>()
{
std::cout << "my thing" << std::endl;
return std::tuple<int, MyType> { 1, {} };
};
int main()
{
auto f = Foo<int>();
auto x = f.Bar<int>();
auto y = f.Bar<std::tuple<int, MyType>>();
}
如果没有,那么你必须让你的成员函数遵从可以部分专业化的函数对象:
#include <iostream>
#include <tuple>
// general case
template<class S, class T, class...Ts>
struct BarOp;
template <typename S>
struct Foo {
template <typename...Ts>
auto Bar() -> decltype(auto)
{
auto op = BarOp<Foo<S>, Ts...>();
return op(this);
}
};
// general case of single T
template<class S, class T>
struct BarOp<S, T>
{
auto operator()(S* p) const
{
std::cout << "usual thing" << std::endl;
return T();
}
};
struct MyType {};
// now partially specialise for T, MyTyoe
template<class S, class T>
struct BarOp<S, T, MyType>
{
auto operator()(S* p) const
{
std::cout << "other thing" << std::endl;
return T(10);
}
};
int main()
{
auto f = Foo<int>();
auto x = f.Bar<int>();
auto y = f.Bar<int, MyType>();
}
预期产出:
usual thing
other thing
答案 1 :(得分:0)
编辑:可以运行:
#include <iostream>
template <typename S>
class Foo {
/* internal use of S */
int bar2(S s);
public:
template <typename T, typename K>
T Bar() {
/* internal use of K, may be also S */
K var = 5.3;
return (T) var; //convert K to T
}
};
int main() {
Foo<int> f;
int res = f.Bar<int, double>();
std::cout <<"res = " << res << std::endl;
return 0;
}