c ++ 11使用已实现的方法的部分类专门化

时间:2014-05-01 17:51:44

标签: templates c++11 partial specialization partial-specialization

安抚此示例代码

#include <vector>
#include <iostream>
#include <algorithm>
#include <unistd.h>

template< typename T, typename S >
class MyClass
{
public:
    MyClass () : v(10) {}
    bool ok () { return true; }
    T run (S s, int i) { return v.at(i) = s(); }

private:
    std::vector<T> v;
};

int main ()
{
    auto f_int = [=]() -> int { sleep(1); return 15; };
    MyClass<int, stdmc::function< int(void) > > mc_int;
    std::cout << mc_int.run(f_int, 1) << std::endl;

    return 0;
}

我想为T=void类型进行部分模板特化,而不重写重复代码。显然,我只需重新实现run并可能删除vector,因为它无法存储void类型。

有很多文献涉及这个主题(使用枚举或int模板参数),但不是类似问题的一个例子(即重新实现一种方法和有问题的vector)。

我的动机很明显 - 我需要为将来的代码修订只编写一次通用方法。

我的尝试(使用上面的代码):

template< typename S >
class MyClass<void, S>
{
public:
    // same constructor
    // same ok() method
    void run (S s, int i) { return s(); }

private:
    // without std::vector<T> v;
};

// ----- main ------
auto f_void = [=]() -> void { sleep(1); };
MyClass<void, std::function< void(void) > > mc_void;
std::cout << mc_void.run(f_void, 1) << std::endl;

有没有办法在c ++ 11中实现这种行为?如果是这样,那么正确的语法是什么?如果没有,你建议什么 - 复制整个类,同时只纠正一个方法或完全重构整个类,以避免这些问题(可能使用vector<T*>应该能够存储void*)?< / p>

1 个答案:

答案 0 :(得分:0)

感谢Oktalist - 这似乎有用

#include <vector>
#include <iostream>
#include <algorithm>
#include <unistd.h>

class Base
{
public:
    bool ok () { return true; }
};

template< typename T, typename S >
class MyClass : public Base
{
public:
    MyClass () : v(10) {}
    T run (S s, int i) { return v.at(i) = s(); }

private:
    std::vector<T> v;
};

template< typename S >
class MyClass<void, S> : Base
{
public:
    MyClass () = default;
    void run (S s, int i) { return s(); }
};

int main ()
{
    auto f_int = [=]() -> int { sleep(1); return 15; };
    MyClass<int, std::function< int(void) > > mc_int;
    std::cout << mc_int.run(f_int, 1) << std::endl;

    auto f_void = [=]() -> void { sleep(1); std::cout << "done" << std::endl; };
    MyClass<void, std::function< void(void) > > mc_void;
    mc_void.run(f_void, 1);

    return 0;

}