使用指针非类型模板参数? [英] Uses of pointers non-type template parameters?

查看:142
本文介绍了使用指针非类型模板参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人使用过指针/引用/指针到成员(非类型)模板参数吗?

我不知道任何C ++场景(理性/真实世界)功能应该作为最佳实践。

Has anyone ever used pointers/references/pointer-to-member (non-type) template parameters?
I'm not aware of any (sane/real-world) scenario in which that C++ feature should be used as a best-practice.

功能的演示(用于指针):

Demonstation of the feature (for pointers):

template <int* Pointer> struct SomeStruct {};
int someGlobal = 5;
SomeStruct<&someGlobal> someStruct; // legal c++ code, what's the use?

任何启发都会受到赞赏!

Any enlightenment will be much appreciated!

推荐答案

指向功能的指针

指向成员函数的指针和指向-function非类型参数对于某些委托确实有用。

Pointer-to-member-function and pointer-to-function non-type parameters are really useful for some delegates. It allows you to make really fast delegates.

例如:

#include <iostream>
struct CallIntDelegate
{
    virtual void operator()(int i) const = 0;
};

template<typename O, void (O::*func)(int)>
struct IntCaller : public CallIntDelegate
{
    IntCaller(O* obj) : object(obj) {}
    void operator()(int i) const
    {
        // This line can easily optimized by the compiler
        // in object->func(i) (= normal function call, not pointer-to-member call)
        // Pointer-to-member calls are slower than regular function calls
        (object->*func)(i);
    }
private:
    O* object;
};

void set(const CallIntDelegate& setValue)
{
    setValue(42);
}

class test
{
public:
    void printAnswer(int i)
    {
        std::cout << "The answer is " << 2 * i << "\n";
    }
};

int main()
{
    test obj;
    set(IntCaller<test,&test::printAnswer>(&obj));
}

此处为示例

指针到数据

您可以使用此类非类型参数来扩展变量的可见性。

You can use such non-type parameters to extend the visibility of a variable.

例如,如果您正在编写一个反射库(这可能会对于脚本编写非常有用),使用宏让用户为库声明他的类,您可能希望将所有数据存储在复杂的结构中(可能会随时间变化),并希望使用某些句柄。

For example, if you were coding a reflexion library (which might very useful for scripting), using a macro to let the user declare his classes for the library, you might want to store all data in a complex structure (which may change over time), and want some handle to use it.

示例:

#include <iostream>
#include <memory>

struct complex_struct
{
    void (*doSmth)();
};

struct complex_struct_handle
{
    // functions
    virtual void doSmth() = 0;
};

template<complex_struct* S>
struct csh_imp : public complex_struct_handle
{
    // implement function using S
    void doSmth()
    {
        // Optimization: simple pointer-to-member call,
        // instead of:
        // retrieve pointer-to-member, then call it.
        // And I think it can even be more optimized by the compiler.
        S->doSmth();
    }
};

class test
{
    public:
        /* This function is generated by some macros
           The static variable is not made at class scope
           because the initialization of static class variables
           have to be done at namespace scope.

           IE:
               class blah
               {
                   SOME_MACRO(params)
               };
           instead of:
               class blah
               {
                   SOME_MACRO1(params)
               };
               SOME_MACRO2(blah,other_params);

           The pointer-to-data template parameter allows the variable
           to be used outside of the function.
        */
        std::auto_ptr<complex_struct_handle> getHandle() const
        {
            static complex_struct myStruct = { &test::print };
            return std::auto_ptr<complex_struct_handle>(new csh_imp<&myStruct>());
        }
        static void print()
        {
            std::cout << "print 42!\n";
        }
};

int main()
{
    test obj;
    obj.getHandle()->doSmth();
}

对不起, auto_ptr shared_ptr 在Codepad和Ideone上均不可用。
实时示例

Sorry for the auto_ptr, shared_ptr is available neither on Codepad nor Ideone. Live example.

这篇关于使用指针非类型模板参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆