C++扩展函数?

123*_*123 15 c++

是否有像C#中的C++扩展?

例如在C#中你可以这样做:

public static uint SwapEndian(this uint value)
{
    var tmp = BitConverter.GetBytes(value);
    Array.Reverse(tmp);
    return BitConverter.ToUInt32(tmp, 0);
}

someuint.SwapEndian();
Run Code Online (Sandbox Code Playgroud)

在C++中有类似的东西吗?

Ale*_* C. 6

扩展方法(以及"静态类")只存在于C#/ Java语言中,因为设计者认为(Java方式)OOP是The One True Way,并且所有内容都必须是来自类的方法:

这不是C++的做事方式.在C++中,您有名称空间,自由函数和Koenig查找来扩展类的行为:

namespace foo
{
    struct bar { ... };

    void act_on_bar(const bar& b) { ... };
}

...

foo::bar b;
act_on_bar(b); // No need to qualify because of Koenig lookup
Run Code Online (Sandbox Code Playgroud)

我通常认为扩展方法有害.如果你对一个类附加太多的行为,你可能无法捕获该类存在的原因.另外(如"部分类"),它们倾向于使代码与非本地类相关.这很糟糕.

至于你的问题,在C++中你只需:

template <typename T>
T swap_endian(T x)
{
    union { T value; char bytes[sizeof(T)]; } u;
    u.value = x;

    for (size_t i = 0; i < sizeof(T)/2; i++) 
        swap(u.bytes[i], u.bytes[sizeof(T) - i - 1]);

    return u.value;
}
Run Code Online (Sandbox Code Playgroud)

用法:

swap_endian<std::uint32_t>(42);
Run Code Online (Sandbox Code Playgroud)

或者,如果可以推断出类型:

std::uint64_t x = 42;
std::uint64_t y = swap_endian(x);
Run Code Online (Sandbox Code Playgroud)

  • 扩展方法只是语法糖..你可以有一个自由函数`act_on_bar`并使用它像`act_on_bar(b)`或`b.act_on_bar()`.第二种方式_nothing_与真正的OO方式_只有可读性.例如,如果你有2个功能; `act2(act1(b))`的可读性低于`b.act1().act2()`.在C++中,你__ to to make`act1`和`act2`成员函数来获取可读代码,即使将它们作为自由函数更有意义!它也会改进泛型编程.可读性在这里不是主观的,因为大多数人从左到右阅读文本,没有从内到外阅读. (4认同)

K-b*_*llo 5

C++中没有扩展函数.您可以将它们定义为自由函数.

uint SwapEndian(uint value){ ... }
Run Code Online (Sandbox Code Playgroud)


Mic*_*son 5

我发现的一种方法是将重载的“>>”运算符与 lambda 表达式一起使用。下面的代码演示了这一点。你必须知道使用运算符“>>”而不是“->”,这是因为我使用的编译器不允许重载运算符“->”。另外,由于运算符“>>”的优先级低于“->”,因此您必须使用括号强制编译器以正确的顺序计算方程。

最终,它变成了您尝试生成的代码的风格、可维护性、可靠性和简洁性的问题。有人会认为用两个参数定义“SubtractValue”方法会创建更高效​​的代码,但其他人会认为重载方法更易于维护。最后,由建筑师和开发人员来决定什么对他们的项目来说是重要的。我只是提供一个可能的解决方案。

#include <functional>
#include <iostream>
#include <stdio.h>
#include <tchar.h>

// Some plain demo class that cannot be changed.
class DemoClass
{
public:
    int GetValue() { return _value; }
    int SetValue(int ivalue) { _value = ivalue; return _value; }
    DemoClass *AddValue(int iadd) { this->_value += iadd; return this; }

private:
    int _value = 0;
};

// Define Lambda expression type that takes and returns a reference to the object.
typedef std::function<DemoClass *(DemoClass *obj)> DemoClassExtension;

// Overload the ">>" operator because we cannot overload "->" to execute the extension.
DemoClass* operator>>(DemoClass *pobj, DemoClassExtension &method)
{
    return method(pobj);
}

// Typical extensions.

// Subtract value "isub".
DemoClassExtension SubtractValue(int isub)
{
    return [=](DemoClass *pobj) {
        pobj->AddValue(-isub);
        return pobj;
    };
}

// Multiply value "imult".
DemoClassExtension MultiplyValue(int imult)
{
    return [=](DemoClass *pobj) {
        pobj->SetValue(pobj->GetValue() * imult);
        return pobj;
    };
}

int _tmain(int argc, _TCHAR* argv[])
{
    DemoClass *pDemoObject = new DemoClass();
    int value = (pDemoObject->AddValue(14) >> SubtractValue(4) >> MultiplyValue(2))->GetValue();
    std::cout << "Value is " << value;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码输出是“Value is 20”。