Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 返回匿名结构的函数是否有合理的用途?_C++_Templates_Memory Leaks_Anonymous Types - Fatal编程技术网

C++ 返回匿名结构的函数是否有合理的用途?

C++ 返回匿名结构的函数是否有合理的用途?,c++,templates,memory-leaks,anonymous-types,C++,Templates,Memory Leaks,Anonymous Types,下面是一个使用函数的(人工)示例,该函数返回匿名结构并执行“某些”有用的操作: #包括 模板 T*func(T*T,浮点a,浮点b){ 如果(!t){ t=新的t; t->a=a; t->b=b; }否则{ t->a+=a; t->b+=b; } 返回t; } 结构{ 浮子a、b; }*浮球(浮球a、浮球b){ 如果(a==0)返回0; 返回函数(foo(a-1,b),a,b); } int main(){ std::cout a目前,您的代码是不可移植的;例如,它不会使用gcc构建 本标准第1

下面是一个使用函数的(人工)示例,该函数返回匿名结构并执行“某些”有用的操作:

#包括
模板
T*func(T*T,浮点a,浮点b){
如果(!t){
t=新的t;
t->a=a;
t->b=b;
}否则{
t->a+=a;
t->b+=b;
}
返回t;
}
结构{
浮子a、b;
}*浮球(浮球a、浮球b){
如果(a==0)返回0;
返回函数(foo(a-1,b),a,b);
}
int main(){

std::cout a目前,您的代码是不可移植的;例如,它不会使用
gcc
构建

本标准第14.3.1/2节规定:

一个本地类型,一个没有 链接,未命名类型或类型
由这些类型中的任何一种复合而成 不得用作模板-
模板的参数
类型参数

关于一种可能的演变,请参见和中的第488项

更新1 假设您的代码格式正确,那么:

  • 您可以重写:

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

    当然,如果您的代码格式神奇地正确,
    std::auto_ptr
    将能够保留匿名类型,并将为您正确、优雅地调用
    delete

    C++标准不允许匿名结构。

    我想不出任何合理的使用方法。除了内存泄漏,这一点非常重要是实现目标的一种非常不可读的方式。它让读者思考代码在做什么。而且不知道谁应该删除main()中的“f”。是否应该使用delete[]或delete删除它

    我将使用一个类,在构造函数中使用“a”和“b”。它将有两个方法来获取两个计算结构成员。在该类中,将有私有mehotd,使用普通循环来计算所需的内容。然后,您的API将如下所示:

    void main()
    {
       MyCalculator myCalc(5, 6);
       double sumOfAllNumbers = myCalc.getSumOfAllNumbers();
       double product = myCalc.getProduct();
    }
    

    您所做的是不可能的,标准的C++类型定义在返回类型中是不允许的,如Po.83.5/6(函数声明符,C++ 03):

    不应在返回或参数类型中定义类型


    Visual Studio在这种情况下是不兼容的。

    匿名结构的近似值是一个元组。现在任何地方都可以使用,TR1中还有一个(我假设它与VS2008一起发布)具有几乎相同的接口

    #include <boost/tuple/tuple.hpp>
    
    template<typename T>
    boost::tuple<T, T>* func(boost::tuple<T, T>* t, float a, float b ) {
        if(!t) {
          t = new boost::tuple<T, T>(a, b);
        } else {
          boost::get<0>(*t) += a;
          boost::get<1>(*t) += b;
        }
        return t;
    }
    
    boost::tuple<float, float>* foo(float a, float b) {
        if(a==0) return 0;
        return func(foo(a-1,b), a, b);
    }
    
    #包括
    模板
    boost::tuple*func(boost::tuple*t,浮点a,浮点b){
    如果(!t){
    t=新的boost::tuple(a,b);
    }否则{
    boost::get(*t)+=a;
    boost::get(*t)+=b;
    }
    返回t;
    }
    boost::tuple*foo(浮点a、浮点b){
    如果(a==0)返回0;
    返回函数(foo(a-1,b),a,b);
    }
    

    正如其他人所说,整体方案非常脆弱,但我想把重点放在元组上,而不是设计上。

    delete[]
    在分配了
    new
    的内存上?哎哟!我知道,我只是想把匿名结构作为一个浮点数组来删除,类似于float*f=new float[2]。我几乎可以肯定你根本无法做到这一点,所以是否有使用并不重要。@Dennis Zickefoose:我可以在VS2008上编译并运行这个,可能会使用一些非标准的扩展。但我肯定它在VS2008上可以工作。试着在删除之后做些什么[];任何事情都可能发生。是的,我想我在我的问题中提到过,这是一个人为的例子,我可以按照你的建议用一种更简单的方法来做。然而,我的问题只是想找到一种方法,这可能是做事情的方法。我相信如果函数返回一些我可以使用的东西,它会很方便访问的各个部分,而不必创建特殊的结构。例如用法:foo(5,6)->a很优雅,我不必为其定义单独的结构名称。无论如何,代码是不可移植的,并且特定于VS2008。谢谢。抱歉,但是'foo(5,6)'->a'可能很方便,但我认为它并不优雅。它很难阅读,因为通常您会调用“object->method()。在本例中,情况正好相反-左侧是一个返回结构的函数,右侧只是一个成员。调试也很困难。但是这个示例对于学生测试很好;)感谢在这个上下文中可能的演变。@Vlad:即使N2657集成了它,由于retu中不允许使用类型定义,它也不可移植rn类型。@gf,没错,当我说
    假设你的代码是格式良好的
    这是一个超越N2657的大假设,但是为了论证起见,让我们假设
    g++
    将来也支持它作为扩展(
    gcc
    在构建C时会很好地吞下它,就像MSVC在OP中所做的那样…)感谢标准参考BTW!:)在更新之前写下。即使如此,C++中没有Kirill的匿名结构。我不认为如果语言不同,我们会讨论什么:好的讨论,但是你能更好地限定你的“近似近似”吗?(即程序员的POV/intent与编译器的POV相反,程序员的意图可能是不必为元组的第n个化身想出另一个类型名,因此代码的可读性可能会受到影响或繁荣。)你可能想让它更精确。在特定情况下,规则1.3.1/2会使它们非法,很明显,规则只在它们通常被允许的情况下才需要。@ MalSalts,通常是允许的,但不是匿名的。第一个是C++,它支持:<代码>结构> {int i;};a. i=0;< /C>(类型没有名称)第二个是C++不支持的:<代码>结构> {int i;};i=0;< />代码(类型没有名称,并且它逃入周围范围)。
     delete (int*)f;
    
    void main()
    {
       MyCalculator myCalc(5, 6);
       double sumOfAllNumbers = myCalc.getSumOfAllNumbers();
       double product = myCalc.getProduct();
    }
    
    #include <boost/tuple/tuple.hpp>
    
    template<typename T>
    boost::tuple<T, T>* func(boost::tuple<T, T>* t, float a, float b ) {
        if(!t) {
          t = new boost::tuple<T, T>(a, b);
        } else {
          boost::get<0>(*t) += a;
          boost::get<1>(*t) += b;
        }
        return t;
    }
    
    boost::tuple<float, float>* foo(float a, float b) {
        if(a==0) return 0;
        return func(foo(a-1,b), a, b);
    }