草庐IT

c++ - 当提供模板参数列表时,继承模板类列表

coder 2024-02-23 原文

我正在尝试编写一些元编程代码:

  • 继承自某个类 foo<c1, c2, c3, ...>结果继承自 key<c1>, key<c2>, key<c3>, ...
  • 最简单的方法并不完全有效,因为您不能多次从同一个空类继承。
  • 处理“...”部分不是很好(因为它是复制面食),但可以。

好的,下面是尝试:

template<char c0, typename THEN, typename ELSE>
struct char_if
{
    typename THEN type;
};
template<typename THEN, typename ELSE>
struct char_if<0, THEN, ELSE>
{
    typename ELSE type;
};
class emptyClass {};


template<char c> class key
{
    char getKey(){return c;}
};

template<char c0, char c1, char c2, char c3, char c4>
class inheritFromAll
{
    typename char_if<c0, key<c0>, emptyClass>::type valid;

    class inherit
        : valid
        , inheritFromAll<c1, c2, c3, c4, 0>::inherit
    {};
};

template<char c1, char c2, char c3, char c4>
class inheritFromAll<0, c1, c2, c3, c4>
{
    class inherit {};
};

template<char c0 = 0, char c1 = 0, char c2 = 0, char c3 = 0, char c4 = 0>
class whatINeedToDo
    : public inheritFromAll<c0, c1, c2, c3, c4>::inherit
{
    bool success(){return true;}

};

int main() 
{
    whatINeedToDo<'A', 'B', 'c', 'D'> experiment;
    return 0;
}

虽然我最初可以使用 Boost::Mpl 来做到这一点,但老实说我不知道​​如何做;我想不通你是怎么传递一个 list<...> 的并不总是明确知道 ...部分。

只是做:

template<> class key<0> {};

不起作用,因为如果我有多个 0参数,我尝试从同一事物继承两次。 (如果您能想到解决方法,那也行)。

我也没有尝试过宏,因为我认为我对它们的了解比我对元编程的了解还少,所以它们可能可以作为一种解决方案。

有什么想法吗?

编辑:我有一个不好的解决方案。我仍然想要一个元编程解决方案,用于学习,但不好的解决方案是这样的:

template<char c1, char c2, char c3> class inheritFromMany
    : public key<c1>
    , public key<c2>
    , public key<c3>
{

};
template<char c1, char c2> class inheritFromMany<c1, c2, 0>
    : key<c1>
    , key<c2>
    {

    };

Edit2:哇,但我忘记了一部分。我需要将一个变量传递给“键”的构造函数 - 在所有情况下都是一样的,但这是必要的。

Edit3:处理评论:

  • 我不希望用户多次提交相同的字符。如果他们这样做了,我只想从那个 key 继承一次——我的意思是,我想我没有提到它是因为你不能那样做?这就是为什么其他更简单的解决方案不起作用的原因?
  • 实际意义在于,key 是信号/槽( channel )行为的包装器。该 channel 保留了一个回调列表,实际上就是 virtual key<ch>::callback .因此,从键继承可以让您访问该键的 channel ,让(或使)您提供回调。 keyInput<ch1, ch2, ch3,...>然后是一个包装器,所以你不必 key<ch1>, key<ch2>, key<ch3>

最佳答案

无需说明您实际想要实现的目标,这主要是学术练习...但这是您如何使用 MPL 进行线性继承的一种方式:

template<class T> struct key {
    enum { value = T::value };
    char getKey() { return value; }
};

template<class Values> struct derivator 
    : mpl::inherit_linearly<
          Values
        , mpl::inherit< mpl::_1, key<mpl::_2> >
        >::type
{};

// usage:    
typedef mpl::vector_c<char, 1,2,3> values;
typedef derivator<values> generated;

// or:
derivator< mpl::vector_c<char, 1,2,3> > derived;

也许你可以在此基础上阐明你需要什么。

I need to pass a variable to the constructor of ''key'' - it's the same in all cases, but it's necessary.

您的意思是要通过继承链将参数传递给所有构造函数吗?然后看看this question的解决方案.


至于在可见界面中避免 mpl::vector_c,您可以使用之前的方法并通过仅在其中插入不等于零的值来在内部构建它:

template<char c, class S> struct push_char {
    typedef typename mpl::push_front<S, mpl::char_<c> >::type type;
};

template<class S> struct push_char<0, S> {
    typedef S type; // don't insert if char is 0
};

template<char c1=0, char c2=0, char c3=0>
struct char_vector { 
    // build the vector_c
    typedef 
        typename push_char<c1
      , typename push_char<c2
      , typename push_char<c3
      , mpl::vector_c<char> 
      >::type>::type>::type
    type; 
};

template<char c1=0, char c2=0, char c3=0> 
struct derivator 
    : mpl::inherit_linearly<
          typename char_vector<c1,c2,c3>::type
        , mpl::inherit< mpl::_1, key<mpl::_2> >
        >::type
{};

关于c++ - 当提供模板参数列表时,继承模板类列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2338049/

有关c++ - 当提供模板参数列表时,继承模板类列表的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  4. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  5. ruby - RVM 使用列表[0] - 2

    是否有类似“RVMuse1”或“RVMuselist[0]”之类的内容而不是键入整个版本号。在任何时候,我们都会看到一个可能包含5个或更多ruby的列表,我们可以轻松地键入一个数字而不是X.X.X。这也有助于rvmgemset。 最佳答案 这在RVM2.0中是可能的=>https://docs.google.com/document/d/1xW9GeEpLOWPcddDg_hOPvK4oeLxJmU3Q5FiCNT7nTAc/edit?usp=sharing-知道链接的任何人都可以发表评论

  6. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  7. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  8. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  9. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  10. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

随机推荐