是否可以在模板专业化中将类模板用作参数?
我希望能够使用类似foo<Foo<int>>()
的内容(请参阅源代码中的#3
),并为该模板实例运行提供唯一代码。目前只有普通的专业化工作(见#2
)。
之前的similar question让我相信方法#3
会起作用,但代码至少在msvc2012下无效。
我正在尝试做什么?如果是这样,怎么样?
来源
// Test struct.
template<class T>
struct Foo
{
T foo;
};
// #1 Ordinary template
template<class T>
T foo()
{
return T();
}
// #2 Template specialization
template<>
int foo<int>()
{
return 42;
}
// #3 Template specialization with template as parameter? Not working.
template<>
template<typename T>
Foo<T> foo<Foo<T>>()
{
return Foo<T>();
}
答案 0 :(得分:2)
函数不能部分专门化,您需要将其包装到类或结构中
#include <iostream>
using namespace std;
// Test struct.
template<class T>
struct Foo
{
T foo;
};
// Struct specialization
template<>
struct Foo<bool>
{
static const int val = 46;
};
// #1 Ordinary template
template<class T>
struct functionWrapper {
static T foo() {
return T();
}
};
// #2 Template specialization
template<>
struct functionWrapper<int> {
static int foo() {
return 42;
}
};
// #3 Template specialization with template as parameter
template<class T>
struct functionWrapper<struct Foo<T>> {
static Foo<T>* foo() {
return new Foo<T>();
}
};
int main() {
cout << functionWrapper<bool>::foo() << endl;
cout << functionWrapper<int>::foo() << endl;
Foo<bool> *obj = functionWrapper<Foo<bool>>::foo();
cout << obj->val;
delete obj; // Always be a good citizen
return 0;
}
答案 1 :(得分:0)
我重写了Marco A.的解决方案,让我保留原始语法。
然后,我还想出了第二个使用&#34; out参数的解决方案&#34;而不是&#34;返回值&#34;。我认为这个解决方案更好,因为维护和完成相同的工作更简单。
解决方案#1 (用原始语法重写了Marco A&#39的解决方案)
#include <iostream>
using namespace std;
// Test struct
template<class T>
struct Foo
{
T foo;
};
// #1 Ordinary template
template<class T>
struct FooWrapper
{
static T foo()
{
return T();
}
};
// #2 Template specialization
template<>
struct FooWrapper<int>
{
static int foo()
{
return 42;
}
};
// #3 Template specialization with template as parameter
template<class T>
struct FooWrapper<Foo<T>>
{
static Foo<T> foo()
{
return Foo<T>();
}
};
// Hides wrapper implementation
template<class T>
T foo()
{
return FooWrapper<T>::foo();
}
int main()
{
cout << foo<bool>() << endl;
cout << foo<int>() << endl;
cout << foo<Foo<int>>().foo << endl;
return 0;
}
解决方案#2 (使用输出参数更简单,可能更好的解决方案)
#include <iostream>
using namespace std;
// Test struct
template<class T>
struct Foo
{
T foo;
int bar;
};
// #1 General case
template<class T>
void foo(T& value)
{
value = T();
}
// #2 Special case
void foo(int& value)
{
value = 2;
}
// #3 Special case with class template
template<class T>
void foo(Foo<T>& value)
{
value.bar = 3;
}
// Function templates with hidden specializations
template<class T>
T foo()
{
T value;
foo(value);
return value;
}
int main()
{
cout << foo<bool>() << endl;
cout << foo<int>() << endl;
cout << foo<Foo<int>>().bar << endl;
return 0;
}