有没有合理的使用一个函数返回一个匿名结构? [英] Is there any reasonable use of a function returning an anonymous struct?

查看:154
本文介绍了有没有合理的使用一个函数返回一个匿名结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是一个使用返回匿名结构并且有用的函数的(人工)示例:

Here is an (artificial) example of using a function that returns an anonymous struct and does "something" useful:

#include <iostream>

template<typename T>
T* func(T* t, float a, float b) {
    if(!t) {
        t = new T;
        t->a = a;
        t->b = b;
    } else {
        t->a += a;
        t->b += b;
    }
    return t;
}

struct {
    float a, b;
}* foo(float a, float b) {
    if(a==0) return 0;
    return func(foo(a-1,b), a, b);
}

int main() {
    std::cout << foo(5,6)->a << std::endl;
    std::cout << foo(5,6)->b << std::endl;

    void* v = (void*)(foo(5,6));
    //[1] delete f now because I know struct is floats only.
    float* f = (float*)(v);

    std::cout << f[0] << std::endl;
    std::cout << f[1] << std::endl;

    delete[] f;

    return 0;
}

有几点我想讨论:


  1. 很明显,这个代码泄漏了,是不是我不能泄漏,不知道底层的结构定义是什么?请参阅注释[1]。

  2. 我必须返回一个指向匿名结构的指针,所以我可以在模板化函数 func ,我可以做类似的事情而不返回指针吗?

  3. 我想最重要的是,有任何(真实世界)的使用吗?

  1. As is apparent, this code leaks, is there anyway I can NOT leak without knowing what the underlying struct definition is? see Comment [1].
  2. I have to return a pointer to an anonymous struct so I can create an instance of the object within the templatized function func, can I do something similar without returning a pointer?
  3. I guess the most important, is there ANY (real-world) use for this at all? As the example given above leaks and is admittedly contrived.

顺便说一下,函数 foo ,b)是,返回一个包含两个数字的结构,从1到a的所有数字的和以及a和b的乘积。

By the way, what the function foo(a,b) does is, to return a struct containing two numbers, the sum of all numbers from 1 to a and the product of a and b.

也许行新T 可能使用boost :: shared_ptr以避免泄漏,但我没有试了一下。这工作吗?

Maybe the line new T could use a boost::shared_ptr somehow to avoid leaks, but I haven't tried that. Would that work?

我想我只是想将匿名结构体删除为一个float数组,像float * f = new float [2]。这可能是错误的,如下面的评论所示,所以可以做什么?我可以删除吗?

I think I was just trying to delete the anonymous struct as an array of floats, something like float* f = new float[2]. Which might be wrong, as the comment below suggests, so what can be done? can I delete at all?

我可以在VS2008上编译和运行这个代码,也许一些非标准的扩展可能正在使用VS,但它运行,并给出15和30作为答案。

I can compile and run this code "as-is" on VS2008, maybe some non-standard extensions might be being used by VS, but it does run and gives 15 and 30 as the answer.

从答案我相信这是一个VS2008具体实体,它不符合标准,因此不便携。太糟糕了,但我希望看到什么伏都教Stackoverflow或Boost人想出了如果这是在他们的武器:)。感谢所有。

From the answers I believe this contraption is a VS2008 specific entity, it is not standards compliant and thus not portable. Too bad though, I would have liked to see what voodoo the Stackoverflow or Boost people came up with if this was in their arsenal :). Thanks all.

推荐答案

现在,您的代码不可移植;例如,它不会用 gcc 构建。

For now, your code is not portable; it will, for example, not build with gcc.

标准的第14.3.1 / 2节说:

Section 14.3.1/2 of the standard says:


本地类型,没有
链接的类型,未命名类型 br>
从任何这些类型复合
不能作为模板使用

参数
作为模板
类型参数。

A local type, a type with no linkage, an unnamed type or a type
compounded from any of these types shall not be used as a template-
argument
for a template type-parameter.

请参阅 C ++标准核心语言缺陷报告,修订版69

See item 488 in the C++ Standard Core Language Defect Reports, Revision 69 and Paper N2657 for one possible evolution.

假设您的代码格式正确,则:

Assuming that your code were well-formed, then:


  1. 能够重写:

  1. you may be able to rewrite:

std::cout << foo(5,6)->a << std::endl;

std::cout << std::auto_ptr(foo(5,6))->a << std::endl;


  • 您可以返回匿名 struct by-value,前提是匿名结构有一个构造函数采用另一种类型(匿名或不是,你可以在你的方法的主体内部初始化) - 除了,当然,如何指定一个构造函数为匿名结构? :)

  • you may return an anonymous struct by-value provided that the anonymous struct had a constructor taking another type (anonymous or not, that you'd be able to initialize inside the body of your method) -- except, of course, how do you specify a constructor for an anonymous struct? :)

    没有真实的用法,我可以看到除了一个非常复杂的方法,试图不给结构分配一个明确的名称;通常使用匿名结构(在C ++中不是技术上合法的,但是由各种编译器作为扩展支持),以便不污染命名空间,通常通过立即实例化(例如,可以看到一次性函子被实例化并传递作为匿名结构 - 技术上不是法律的C ++。)

    no real-world use that I can see other than an extremely convoluted way of trying not to assign an explicit name to the structure; one would typically use anonymous structs (not technically legal in C++, but supported by various compilers as extensions) in order to not pollute the namespace, typically by instantiating one right away (you may for example see one-shot functors being instantiated and passed down as anonymous structs -- again, technically not legal C++.)



    UPDATE 2


    感谢 gf 指向C ++标准的相关部分的链接,涉及可能未在返回类型中定义的新类型。

    UPDATE 2

    Thank you gf for the link to the relevant portion of the C++ standard concerning new types which may not be defined in a return type.

    从注释中移除此处:调用 delete [] new (相对于 new [] )分配的内存是对堆损坏的邀请。调用 delete 在你不知道的类型的指针在技术上是未定义的(析构函数应该被调用?),但是在POD(你的匿名结构是一个)的情况下,你可以以这种可怕的黑客方式逃避:

    Bringing this one out here from the comments: calling delete[] on memory allocated with new (as opposed to new[]) is an invitation to heap corruption. Calling delete on a pointer whose type you do not know is technically undefined (which destructor should get called?) but in the case of PODs (your anonymous struct being one) you can get away with it in this horrible hackish way:

     delete (int*)f;
    

    当然,你的代码是神奇的, std :: auto_ptr 将能够保留匿名类型,并将正确和优雅地处理调用 delete

    Of course, were your code magically well-formed, std::auto_ptr would have been able to retain the anonymous type and would have taken care of calling delete for you correctly and gracefully.

    这篇关于有没有合理的使用一个函数返回一个匿名结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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