Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 部分模板专门化,不完整类型的使用无效_Templates_C++11_Partial Specialization - Fatal编程技术网

Templates 部分模板专门化,不完整类型的使用无效

Templates 部分模板专门化,不完整类型的使用无效,templates,c++11,partial-specialization,Templates,C++11,Partial Specialization,我有三个示例程序,其中两个可编译,一个不可编译。这三个版本都是使用命令行g++4.8.1编译的:g++--std=c++11-Wall-pedantic-o foo foo.cc。所讨论的代码是一个一次性的示例,旨在展示问题,但其本身并不是有用的 潜在的问题是一个模板类,它需要专门化来处理std::promise::set_value()不接受任何参数的事实。此问题出现在Foo::\u call()方法中 我要使用的版本,称为版本A,失败: #include <future> te

我有三个示例程序,其中两个可编译,一个不可编译。这三个版本都是使用命令行g++4.8.1编译的:
g++--std=c++11-Wall-pedantic-o foo foo.cc
。所讨论的代码是一个一次性的示例,旨在展示问题,但其本身并不是有用的

潜在的问题是一个模板类,它需要专门化来处理
std::promise::set_value()
不接受任何参数的事实。此问题出现在
Foo::\u call()
方法中

我要使用的版本,称为版本A,失败:

#include <future>

template <typename A, typename T>
class Foo
{
  private:
    std::function<T ()> _f;
    std::promise<T> _p;

    static void _call(std::function<T ()> &f, std::promise<T> &p) {
        p.set_value(f());
    }

  public:
    Foo(std::function<T ()> x) : _f(x) {}

    void set_promise() {
        _call(_f, _p);
    }
};

template<typename A>
inline void Foo<A, void>::_call(
    std::function<void ()> &f, std::promise<void> &p)
{
    f();
    p.set_value();
}

int bar()
{
    return 4;
}

void baz()
{
}

int main()
{
    Foo<int, int> a(bar);
    a.set_promise();
    Foo<int, void> b(baz);
    b.set_promise();
}

测试C也可以编译。它将
\u call()
静态方法从
Foo
中拉出来,成为一个模板函数。我也不想这样做,因为
\u call
应该属于
Foo
。虽然这样做有效,但并不雅观

#include <future>

template<typename T>
inline void _call(std::function<T ()> &f, std::promise<T> &p)
{
    p.set_value(f());
}

template<>
void _call(std::function<void ()> &f, std::promise<void> &p)
{
    f();
    p.set_value();
}

template <typename A, typename T>
class Foo
{
  private:
    std::function<T ()> _f;
    std::promise<T> _p;

  public:
    Foo(std::function<T ()> x) : _f(x) {}

    void set_promise() {
        _call(_f, _p);
    }
};

int bar()
{
    return 4;
}

void baz()
{
}

int main()
{
    Foo<int, int> a(bar);
    a.set_promise();
    Foo<int, void> b(baz);
    b.set_promise();
}
#包括
模板
内联void_调用(std::function&f,std::promise&p)
{
p、 设置_值(f());
}
模板
void_调用(std::function&f,std::promise&p)
{
f();
p、 设置_值();
}
模板
福班
{
私人:
std::function\u f;
std::promise\u p;
公众:
Foo(std::function x):\u f(x){}
无效集合_承诺(){
_调用(_f,_p);
}
};
整型条()
{
返回4;
}
void baz()
{
}
int main()
{
富a(酒吧);
a、 设定承诺();
富b(baz);;
b、 设定承诺();
}


所以,问题是,A为什么会失败?有没有一种方法可以在不使用B或C的情况下解决这个问题?

部分模板专门化只适用于整个类模板。您不能只对一个成员进行部分专业化

一种解决方案是引入一个基类并专门化它

#include <future>

template< typename T >
struct Foo_base {
    static void _call(std::function<T ()> &f, std::promise<T> &p) {
        p.set_value(f());
    }
};

template<>
struct Foo_base< void > {
    static void _call(std::function<void ()> &f, std::promise<void> &p)
    {
        f();
        p.set_value();
    }
};

template <typename A, typename T>
class Foo : Foo_base< T >
{
private:
    using Foo::Foo_base::_call;
    std::function<T ()> _f;
    std::promise<T> _p;

public:
    Foo(std::function<T ()> x) : _f(x) {}

    void set_promise() {
        _call(_f, _p);
    }
};
#包括
模板
结构Foo_base{
静态void_调用(std::function&f,std::promise&p){
p、 设置_值(f());
}
};
模板
结构Foo_base{
静态void_调用(std::function&f,std::promise&p)
{
f();
p、 设置_值();
}
};
模板
类Foo:Foo_base
{
私人:
使用Foo::Foo_base::_调用;
std::function\u f;
std::promise\u p;
公众:
Foo(std::function x):\u f(x){}
无效集合_承诺(){
_调用(_f,_p);
}
};
#include <future>

template<typename T>
inline void _call(std::function<T ()> &f, std::promise<T> &p)
{
    p.set_value(f());
}

template<>
void _call(std::function<void ()> &f, std::promise<void> &p)
{
    f();
    p.set_value();
}

template <typename A, typename T>
class Foo
{
  private:
    std::function<T ()> _f;
    std::promise<T> _p;

  public:
    Foo(std::function<T ()> x) : _f(x) {}

    void set_promise() {
        _call(_f, _p);
    }
};

int bar()
{
    return 4;
}

void baz()
{
}

int main()
{
    Foo<int, int> a(bar);
    a.set_promise();
    Foo<int, void> b(baz);
    b.set_promise();
}
#include <future>

template< typename T >
struct Foo_base {
    static void _call(std::function<T ()> &f, std::promise<T> &p) {
        p.set_value(f());
    }
};

template<>
struct Foo_base< void > {
    static void _call(std::function<void ()> &f, std::promise<void> &p)
    {
        f();
        p.set_value();
    }
};

template <typename A, typename T>
class Foo : Foo_base< T >
{
private:
    using Foo::Foo_base::_call;
    std::function<T ()> _f;
    std::promise<T> _p;

public:
    Foo(std::function<T ()> x) : _f(x) {}

    void set_promise() {
        _call(_f, _p);
    }
};