我正在尝试编写一个包含多个类型参数T1
和T2
的模板类。该类有一个std::promise<T2>
类型的私有成员。
template <class T, class T2>
class Test
{
public:
void setValue(T2 value)
{
promise.set_value(value);
}
void setValue()
{
promise.set_value();
}
private:
std::promise<T2> promise;
};
当T2
是空的时候,这个类编译得很好(只要你没有参数就调用setValue
。当T2
无效时,我得到编译错误:
error C2182: 'value' : illegal use of type 'void'
当T2
无效时,我想使用第一个setValue
方法,该方法具有T2
类型的单个参数。当T2
无效时,我想使用第二个setValue
方法,该方法不带参数。我看了很多例子,但我对模板编程比较陌生,而且我似乎无法使它工作。
是否有可能以某种方式使用std :: enable_if完成此操作?或者使用模板专业化?
答案 0 :(得分:2)
帮助器模板类专业化:
#include <future>
template<typename T>
class TestHelper
{
public:
void setValue(T const& v)
{ promise.set_value(v); }
private:
std::promise<T> promise;
};
template<>
class TestHelper<void>
{
public:
void setValue()
{ promise.set_value(); }
private:
std::promise<void> promise;
};
template <class T, class T2>
class Test : public TestHelper<T2>
{
};
int main()
{
Test<void, int> t;
// t.setValue(); // compilation error: no matching function for call to 'std::promise<int>::set_value()'
t.setValue(0);
Test<void, void> t1;
t1.setValue();
// t1.setValue(0); // compilation error: no matching function for call to 'std::promise<void>::set_value(int)'
}
答案 1 :(得分:0)
您可以通过对基类的条件依赖来解决此问题:
#include <future>
#include <type_traits>
#include <iostream>
template<class T2>
struct Base {
protected:
std::promise<T2> promise;
};
template<class T2>
struct BaseWithVariable : public Base<T2> {
void setValue(T2 value)
{
this->promise.set_value(value);
}
};
template<typename T2>
struct BaseWithoutVariable : public Base<T2> {
void setValue()
{
this->promise.set_value();
}
};
template<typename T, typename T2>
class Test
: public std::conditional<std::is_same_v<T2, void>, BaseWithoutVariable<T2>, BaseWithVariable<T2>>::type
{
};
int main()
{
Test<int, int> a;
a.setValue(5);
Test<int, void> b;
b.setValue();
}
现在你意识到你可以在中级的水平上实现同样的专业化:
template<class T2>
struct BaseSetter : public Base<T2> {
void setValue(T2 value)
{
this->promise.set_value(value);
}
};
template<>
struct BaseSetter<void> : public Base<void> {
void setValue()
{
this->promise.set_value();
}
};
template<typename T, typename T2>
class Test : public BaseSetter<T2>
{
};
在这种特殊情况下,如果省略Base
的使用并且BaseSetter
的两个变体都使用自己的成员变量std::promise<T2>
,或{{}},也不会受到伤害。 1}},分别。
然而,所有这些都在GCC 7.2.0运行时崩溃。我不知道为什么。