类模板作为模板specializationa中的参数

时间:2014-06-21 16:47:21

标签: c++ templates template-specialization

是否可以在模板专业化中将类模板用作参数?

我希望能够使用类似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>();
}

2 个答案:

答案 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;
}

http://ideone.com/8TXJH4

答案 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;
}