2017-09-26 60 views
2

我正在尝试编写一个具有多个类型参数的模板类T1T2。该班有一个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做到这一点?还是模板专业?

回答

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)' 
} 
+0

复制我的答案。 ;) – ypnos

+0

@ypnos:检查你的编辑时间戳 –

+0

谢谢,解决了它!但是,我有另一种访问'promise'的方法,这是'Test'无法访问的。我应该在哪里放置这种方法?我当然可以保护它,但我只是想知道它是否可以以不同的方式完成。 – jkokorian

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>std::promise<void>

但是,所有这些在运行时崩溃与GCC 7.2.0。我不知道为什么。

相关问题