C++ C++;11:根据容器专门化/限制方法';s值_型
我有一个模板C++ C++;11:根据容器专门化/限制方法';s值_型,c++,c++11,sfinae,specialization,C++,C++11,Sfinae,Specialization,我有一个模板action方法,可以接受任何类型的STL容器C。但是,包含的项目(C::value\u type)必须是ClassA或ClassB。到目前为止一切顺利: struct Whatever { template<typename C> void action(const C& c) { static_assert(std::is_same<typename C::value_type, ClassA>::value ||
action
方法,可以接受任何类型的STL容器C
。但是,包含的项目(C::value\u type
)必须是ClassA
或ClassB
。到目前为止一切顺利:
struct Whatever {
template<typename C>
void action(const C& c) {
static_assert(std::is_same<typename C::value_type, ClassA>::value ||
std::is_same<typename C::value_type, ClassB>::value,
"Wrong C::value_type");
// do something with c
}
};
// Usage:
Whatever w;
w.action(std::vector<ClassA>{1, 2, 3});
w.action(std::unordered_set<ClassB>{1, 2, 3});
struct随便什么{
模板
无效行动(常数C&C){
静态断言(std::is_same::value)||
std::值是否相同,
“错误的C::value_type”);
//用c做点什么
}
};
//用法:
无论w;
w、 作用(std::向量{1,2,3});
w、 动作(std::无序_集{1,2,3});
注意:封闭类不是一个模板,唯一的模板就是这个action
方法
现在,根据C::value\u type
,我想专门化方法的行为。你猜对了,这就是我的大脑开始融化的地方
我相信SFINAE是一个不错的选择,但显然我太生疏了,无法让它正常工作:几个小时后,大量的helper
structs
,为了我自己的健康喝了太多咖啡,编译器只是一直对我大喊通常的500多个模板错误。复制我的helperstructs
或此处的错误都没有意义,这些都是无用的垃圾
然而,我不得不承认,我并没有真正接触到所有的C++模板(R)的演化(甚至使用Sfaye),因为这是一个好的十年,所以难怪我会这么难。
我强烈怀疑C++11现在有了易于使用的类似SFINAE的工具来实现我想要的,但我甚至不知道从哪里开始在文档中搜索。搜索引擎也帮不上忙,一次有太多的新信息让我无法理解什么与我的问题有关
因为我完全不知所措,所以我只需要迈出一小步,然后问你。。。我的问题有两个方面:
- 如何使用现代C++11模板工具根据
的实际类型专门化方法的行为?C::value\u type
- 或者,是否有标准方法检查
是否确实是一个容器?C
谢谢您的关注。我想知道您为什么不这样做:
template<typename C>
void action(const C& c)
{
static_assert(std::is_same<typename C::value_type, ClassA>::value ||
std::is_same<typename C::value_type, ClassB>::value,
"Wrong C::value_type");
action_worker(c, static_cast<typename C::value_type*>(0));
}
private:
template<typename C>
void action_worker(const C& c, ClassA *)
{
//specialized code when C::value_type is ClassA
}
template<typename C>
void action_worker(const C& c, ClassB *)
{
//specialized code when C::value_type is ClassB
}
模板
无效行动(常数C&C)
{
静态断言(std::is_same::value)||
std::值是否相同,
“错误的C::value_type”);
动作工人(c,静态演员(0));
}
私人:
模板
无效操作工人(施工C&C,A类*)
{
//C::value_类型为ClassA时的专用代码
}
模板
无效操作工人(施工C&C,B类*)
{
//C::value_类型为ClassB时的专用代码
}
现在,根据C::value\u type
,action\u worker
的第二个参数可以是ClassA*
或ClassB*
。这将使编译器能够在编写专用代码的地方选择正确的重载
关于问题的第二部分,请参见此答案中的is_container
类模板的实现:
<>希望有帮助。 当你只支持这两种类型时,我会考虑使用Enableα:
struct Whatever
{
template<typename C>
typename std::enable_if<std::is_same<typename C::value_type, ClassA>::value, void>::type
action(const C& c)
{
std::cout << "ClassA\n";
}
template<typename C>
typename std::enable_if<std::is_same<typename C::value_type, ClassB>::value, void>::type
action(const C& c)
{
std::cout << "ClassB\n";
}
};
struct随便什么
{
模板
typename std::enable_if::type
行动(const C&C)
{
std::噢,天哪,我真傻……我本该想到这一点,但我一直在朝着一个可能永远不会想到的相反方向搜索。谢谢!这绝对是对我问题第一部分的一个很好的回答,非常直截了当。@syam:请参阅编辑。它链接到你问题第二部分的解决方案。Than又是ks,你搞定了。真希望我能再次击败你。;(事实上,这正是我最初追求的东西。谢谢,现在我有地方开始调查这些新功能了……:)