【问题标题】:Static array of const pointers to overloaded, templatized member function指向重载的模板化成员函数的 const 指针的静态数组
【发布时间】:2010-11-28 07:07:07
【问题描述】:

静态数组初始化...使用 const 指针...指向重载的模板化成员函数。有没有办法可以做到(C++03标准代码)?我的意思是,如果我有模板类

模板 类 Some_class { 民众: 类型定义 T1 T; 类型定义 U1 U; 类型定义 R1 R; R operator()(T& v) { /* 指向派生类 (U) 的解引用指针, 重载成员函数 (U::f) */ }; 私人的: static R (U::* const pmfi[/* #U中的重载函数*/])(T&); }; 用作 模板 类 Other_class : public Some_class, RET> { RET f(/* 从 BASE 派生的类型 */) {} RET f(/* 从 BASE 派生的其他类型 */) {} RET f(/* 从 BASE 派生的另一种类型 */) {} ... }; 问题:如何初始化 de 数组 pmfi(请不要使用 typedef)?

注意事项:
1. 由于必须在文件范围内初始化静态数组,因此模板参数和 pmfi 必须是完全限定的(我知道在类范围之外访问模板参数的唯一方法是对它们进行 typedef...)。
2. 到目前为止一切顺利。编译器没有问题(Comeau 4.3.10.1)。当我尝试填满初始化列表 { ... } 时,问题开始出现。
2.1。无论我做什么,编译器都会抱怨模板参数列表丢失。
2.2.我不知道如何选择正确的重载 U::f 函数。

顺便说一句,这是一种来自 boost.preprocessor 列表的“跳转表”生成器。我试图实现的代码当然比这个复杂得多,但这就是他的本质。

感谢您的帮助

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    要以您所展示的方式使用BOOST_PP_ENUM,您需要一个宏,它接受一个“数字”并产生一个表达式,该表达式是相应类的相应成员的地址。除非所需的函数都具有制造名称(例如memfun1memfun2 等),否则如果没有明确的列表,我看不到这样做的好方法。除了这种情况,明确列出使用 BOOST_PP_ENUM 的函数地址表达式会更容易。

    您在此数组中使用的标识符与Some_class 中的模板参数相同。

    R (U::* const pmfi[])(T&) = { /* ... */ }
    

    这真的应该是 Some_class 的模板成员吗?

    template< class T, class U, class R >
    R (U::* const Some_class<T, U, R>::pmfi[])(T&) = { /* ... */ }
    

    如果是这样,相同的实例化是否适用于您将模板Some_class 使用的所有类型组合?如果是这样,您有一组非常有限的类,也许您可​​以取消模板。如果没有,您将不得不为模板参数的每个组合专门化Some_class,在这种情况下,模板不会让您受益匪浅。

    编辑,后编辑:如果我的理解正确,那么你不能按照你的建议去做,因为指针数组必须具有完全正确的签名。

    把它简化为一个简单的函数指针示例,你不能这样做:

    void f(Derived&);
    
    void (*p)(Base&) = &f;
    

    否则会破坏类型安全:

    OtherDerived od; // derived from Base, but no from Derived
    
     // I've managed to pass something that isn't a Derived reference to f
     // without an explicit (and dangerous) cast
    (*p)(od);
    

    在你的函数指针数组中,初始化器必须都是正确签名的函数。

    【讨论】:

    • 嗨,Charles 1. 事实上,我使用 boost.preprocessor 中的“seq”来扩展 BOOST_PP_ENUM 并生成类型列表(在该过程中使用) 2. 这些不是真正的代码。代码中的标识符应该是模板 args 的 typedef 如果 R、T、U 是 Some_class 的模板 args 的 typedef(忘记其余的),数组定义将是 Some_class::R (Some_class::U::* const Some_class::pmfi[])(Some_class::T&) = { ... };问:这应该是 ... 部分的语法? A: &Some_class::U::f (重载了 f?)如果 U 本身就是一个模板,那怎么说呢? Comeau 不同意我的尝试
    • 我的意思是U是Some_class的模板参数,但是如果U代表类模板,那么函数U::f的地址应该怎么写呢? &U::f?如何选择合适的重载f?你说对了。顺便说一句,即使对于 1 个 elem 数组(因此没有重载),comeau 编译器也不接受上述 sintax。
    • "那些不是真正的代码。"那么您能否仔细发布一些真实代码并描述您要解决的问题。您的解决方案看起来过于复杂,但不知道问题是什么,很难说。特别是,您能否发布一个您想用于模板参数U 的示例类(或者现在是U1?)以及Types 和元函数Length 的定义位置?编辑后,您现在似乎在Some_class::pmfi 的声明中有错误。
    • 对不起。我重新定义了这个问题(我希望去掉不需要的信息)。
    • 我害怕答案是函数签名。由于您可以将派生类的对象分配给基类指针,我认为基类指针可以接受派生成员类函数的地址。真丢人!感谢您花时间回答这么愚蠢的问题。
    猜你喜欢
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    相关资源
    最近更新 更多