【发布时间】:2016-05-17 16:39:25
【问题描述】:
当我得到这个问题的完美答案时: Specializing class with SFINAE
为了完整起见,我再次在此处插入正确的解决方案作为示例:
class AA { public: using TRAIT = int; };
class BB { public: using TRAIT = float; };
template < typename T, typename UNUSED = void> class X;
template < typename T >
class X<T, typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, void >::type>
{
public:
X() { std::cout << "First" << std::endl; }
};
template < typename T >
class X<T, typename std::enable_if< !std::is_same< int, typename T::TRAIT>::value, void >::type>
{
public:
X() { std::cout << "Second" << std::endl; }
};
int main()
{
X<AA> a;
X<BB> b;
}
但如果我必须使用参数包以供进一步使用,我认为没有机会写下如下内容:
template < typename T, typename ...S, typename UNUSED = void> class X;
错误:参数包'S'必须在模板参数列表的末尾
以不同的顺序定义,例如
template < typename T, typename UNUSED = void, typename ...S> class X;
如果第一个附加类型正在使用,则会出现问题。
好的,我描述的是一个我实际上找不到的技术解决方案。也许有一个不同的。我的根本问题是什么:我需要 2 个不同的构造函数来调用不同的基类构造函数。但是由于两个构造函数都有相同的参数集,我认为没有机会专门化构造函数本身。
如果specialize构造函数可以工作,它可以是这样的:
template < typename T>
class Y
{
public:
template <typename U = T, typename V= typename std::enable_if< std::is_same< int, typename U::TRAIT>::value, int >::type>
Y( const V* =nullptr) { std::cout << "First" << std::endl; }
template <typename U = T, typename V= typename std::enable_if< !std::is_same< int, typename U::TRAIT>::value, float >::type>
Y( const V* =nullptr) { std::cout << "Second" << std::endl; }
};
错误:'模板模板 Y::Y(const V*)' 不能被重载
但正如已经提到的......我不知道是否可以这样做。
为了说明根本问题,我将给出以下示例,该示例显示了基类构造函数的不同用法,具体取决于基类中定义的特征。
template <typename T, typename ... S>: public T
class Z
{
public:
// should work if T defines a trait
Z( typename T::SomeType t): T( t ) {}
// should be used if T defines another trait
Z( typename T::SomeType t): T( ) {}
};
【问题讨论】:
-
“构造函数不能重载”问题可以通过向其中一个构造函数添加一个虚拟和默认模板参数(如
, typename Z = void)来解决,但最后的代码sn-p 说“如果 T 没有定义这个 trait,应该使用”,你的意思是如果::TRAIT不存在? -
@Holt 不,特征是一个自己的模板类,它也使用一个参数包。使用 sfinae 我必须检查该类型的参数包是否为空。我避免了这种特殊的事情,以使其在这里不会变得更复杂。
-
您能否向我们展示带有非工作重载构造函数的完整代码,因为正如@PiotrSkotnicki 提到的,您的问题似乎包含两个不同的问题(检查
TRAIT是否存在并检查TRAIT是否为特定类型)。 -
@Holt:对不起,我在问题中更正了这一点。我需要检查我的特质是否满足某些条件。该特征始终存在。
-
@PiotrSkotnicki 好的,我测试了这个想法。我想知道 sfinae 发生在检查重载规则之后,如果只有一个 SFINAE 表达式有效,这也会导致相同函数的两倍。