使用 C++ 封装简单类型 模板

发布于 2024-07-13 08:47:59 字数 749 浏览 7 评论 0原文

我希望为 C++ 中的所有简单类型添加功能。

我想编写一个模板类,它将要封装的类型作为模板参数,然后定义所有运算符,以便封装的类与它封装的简单类型完全相同。

像这样的事情:

template <typename _SimpleType_>
class Attribute
{
public:
    Attribute(_SimpleType_ value){ m_value = value; }
    ~Attribute(){}

    // Cast
    operator _SimpleType_() { return(m_value); }

    // Comparisons
    bool operator==(const a& other) const { return a == m_value; }
    etc...

private:
   _SimpleType_ m_value;
}

// Use like:
Attribute<int> i = 20;

while(i)
{
   if((i & 0xF) == 0)
   {
      i >>= 2;
   }

   i--;
}  etc...

问题是我确信必须处理大量细微差别并编写专门的模板运算符; 那么是否有任何地方已经完成了此操作,以便我可以使用它来代替?

Boost 太大且复杂,无法放入我的项目中,但如果其中有这样的类,我可以查看它以获取指针 - 如果有,它的名字是什么?

I'm looking to add functionality to all the simple types in C++.

I want to write a single templated class that takes as a template parameter the type to be encapsulated and then has all the operators defined so that the encapsulated class works exactly as the simple type it encapsulates.

Something like this:

template <typename _SimpleType_>
class Attribute
{
public:
    Attribute(_SimpleType_ value){ m_value = value; }
    ~Attribute(){}

    // Cast
    operator _SimpleType_() { return(m_value); }

    // Comparisons
    bool operator==(const a& other) const { return a == m_value; }
    etc...

private:
   _SimpleType_ m_value;
}

// Use like:
Attribute<int> i = 20;

while(i)
{
   if((i & 0xF) == 0)
   {
      i >>= 2;
   }

   i--;
}  etc...

The question is I'm sure there are a load of nuances that have to be dealt with and specialised template operators written; so is there anywhere that this has already been done so that I can just use that instead?

Boost is too large and complicated to put in my project but I can look at it for pointers if there is a class like this in there - whats its name if there is?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时光匆匆的小流年 2024-07-20 08:47:59

这非常简单,如果乏味的话,您只需实现标准类型支持的所有运算符,而强制转换运算符是不够的。

但我不得不问,你到底为什么要这样做?

It's pretty simple, if tedious, - you just have to implement all the operators supported by the standard types and where the cast operator is not sufficient.

I have to ask though, why on earth are you trying to do this?

慕烟庭风 2024-07-20 08:47:59

下面是一个自动类型转换为 T& 的示例。 (使用 GNU C++ 4.3.2 进行测试):

#include <iostream>

using namespace std;

template <typename T>
class Attribute {
public:
    Attribute(const T &value) { v = value; }
    operator T & () { return v; }
private:
    T v;
};

int main(int argc, char **argv)
{
    Attribute<int> i(0);
    i = 3;
    i++;
    i += 4;
    i = i + 5;
    i <<= 3;
    cout << "i is now " << i << endl;
}

C++ 编译器使用强制运算符“operator T &”自动将对“Attribute”的引用强制转换为对“int”的引用。 ()'。 因此,当 Attribute 类不提供“++”运算符或任何内容时,该对象将被类型转换为 int & 然后从那里查找操作员。 请随意尝试。

Here is an example of doing with an automatic typecast to T& (tested with GNU C++ 4.3.2):

#include <iostream>

using namespace std;

template <typename T>
class Attribute {
public:
    Attribute(const T &value) { v = value; }
    operator T & () { return v; }
private:
    T v;
};

int main(int argc, char **argv)
{
    Attribute<int> i(0);
    i = 3;
    i++;
    i += 4;
    i = i + 5;
    i <<= 3;
    cout << "i is now " << i << endl;
}

The C++ compiler casts automagically the reference to 'Attribute' to a reference to 'int' using the coercion operator 'operator T & ()'. So when the Attribute class does not provide the '++' operator or anything, the object is typecasted to int & and then the operator is looked up from there. Feel free to experiment.

浮生面具三千个 2024-07-20 08:47:59

您只需转换为 _Simple_type_ 即可免费获得非变异运算符的实现(并且您可以通过转换为 _Simple_type_& 来获得赋值和递增/递减)。 另一个问题是这是否真的是一个好主意,因为它创建了 TAttributeAttributeT 的转换。 code>T 会在重载时导致问题 - 但您可以通过显式显示 Attribute 的构造函数来解决该问题。

这留下了分配和递增/递减——你只需要实现这些。

另一种可能性是使用 boost::operators - 一个仅标头的库,有助于根据代数规则创建运算符重载。 例如。 您创建operator+=,它将为您提供operator+。 您创建 operator<operator== ,它会给您其他关系等。

You can get the implementation of the nonmutating operators for free, just by the conversion to _Simple_type_ (and you would get the assignments and increment/decrement by conversion to _Simple_type_&). Another question is whether this is really a good idea, as it creates conversions both T to Attribute<T> and Attribute<T> to T which causes problems while overloading - but you could fix that by making the constructor of Attribute<T> explicit.

This leaves the assignments and increment/decrement - you would just have to implement those.

Another possibility is using boost::operators - a header only library that facilitates creation of operator overloads based on algebraic rules. eg. you create operator+=, and it will provide you operator+. You create operator< and operator== and it will give you the other relationals etc.

心如狂蝶 2024-07-20 08:47:59

与您的问题无关,但您应该知道诸如 _SimpleType_ 之类的名称(即以下划线和大写字符开头的名称)是为 C++ 编译器和标准库实现者保留的use - 不允许您在自己的代码中使用它们。

Not to do with your question, but you should be aware that names such as _SimpleType_ (that is, names that begin with an underscore and an uppercase character) are reserved for the C++ compiler and Standard Libarary implementors to use - you are not allowed to use them in your own code.

冰火雁神 2024-07-20 08:47:59

我不确定 boost::ref 是否是您正在寻找的。

无论如何,您要做的最好的事情就是用手写出来——但是如果您打算支持指针和引用语义,这将开始成为一个问题。

您可能还需要做的是将其放入命名空间中并实现自由函数运算符重载,并依赖 ADL 来获取它。 但是,当您实现越来越多的运算符时,这会变得有点笨拙。

I'm not sure if boost::ref is what you're looking for.

At any rate, the best thing you'd do is to just write it out by hand -- but this will start becoming a problem if you intend to support pointer and reference semantics.

What you'd also proabably need to do is put it in a namespace and implement the free function operator overloads and rely on ADL for it to get picked up. This will get a little unwieldy though as you implement more and more operators.

静待花开 2024-07-20 08:47:59

我喜欢这种简单类型的封装形式(原作者 - Sektor van Skijlen):

template<typename T>
class explicit_t
{
private:
    T value;

    template<typename V> explicit_t(V t);
public:
    operator T&() {return value;}
    explicit_t(const T& c) : value(c) {}    
}; 

还有一个简短的示例:

void fun(explicit_t<int> foo) {}

int main()
{
        // fun('a');
        // fun(3u);
        // fun(3.0);
        fun(4);
}

那么我会得到什么? 不再有不需要的转换。

您可能还想看看一些更奇特的东西 - typegen

I like this form of encapsulation of simple types (original author - Sektor van Skijlen):

template<typename T>
class explicit_t
{
private:
    T value;

    template<typename V> explicit_t(V t);
public:
    operator T&() {return value;}
    explicit_t(const T& c) : value(c) {}    
}; 

And the short example:

void fun(explicit_t<int> foo) {}

int main()
{
        // fun('a');
        // fun(3u);
        // fun(3.0);
        fun(4);
}

So what do I get? No more unwanted conversions.

You might also want to have a look at something more fancy - typegen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文