Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/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
C++ C++;11:根据容器专门化/限制方法';s值_型_C++_C++11_Sfinae_Specialization - Fatal编程技术网

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多个模板错误。复制我的helper
structs
或此处的错误都没有意义,这些都是无用的垃圾

然而,我不得不承认,我并没有真正接触到所有的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,你搞定了。真希望我能再次击败你。;(事实上,这正是我最初追求的东西。谢谢,现在我有地方开始调查这些新功能了……:)