标签: forward-declaration

C++提升前瞻性声明问题

我花了一些时间来检查boost::库架构,并对以下事实感兴趣:

在库的某些部分中,使用的yyy_fwd.hpp想法很常见(参见boost/detailboost/flyweight示例).

这些文件显然只包含一些基于模板的类的前向声明,据我所知,可以在编译时间方面受益.

有人可以指出它们在什么情况下有所帮助,我应该在设计自己的模板时使用相同的想法吗?

谢谢.

c++ boost forward-declaration

10
推荐指数
1
解决办法
4304
查看次数

为什么没有<stlfwd>标题并且它的不存在可以被认为是缺陷?

标准库包括一个<iosfwd>头,(forward)声明所有流,包括任何typedefs,并定义char_traits模板,包括特化.

遗憾的是,不存在这样<stlfwd>的是(正向)宣布所有常见的STL的数据类型和功能,如头vector,map,less,sort等.甚至更不幸的是,用户代码不允许这种声明/添加typedefs到的std名称空间,如每

§17.4.3.1 [lib.reserved.names] p1:

除非另有说明,否则C++程序未定义向命名空间内的命名空间或命名空间添加声明或定义.程序可以将任何标准库模板的模板特化添加到命名空间.stdstdstd

是的,它涵盖(前向)声明的情况,即使标准库中已存在类型.当然,即使添加了这样的声明,大多数(所有?)编译器也会表现得非常正常,但严格来说,语言律师说,这是未定义的行为.我觉得这typedef对标准容器来说特别乏味,比如:

// how to forward declare map and string?

typedef std::map<std::string, std::string> Attributes;
Run Code Online (Sandbox Code Playgroud)

现在,这可以被视为缺陷吗?

我的意思是不存在<stlfwd>标题(或者更好<stdfwd>,也包括覆盖<iosfwd>)和标准库中已经存在的声明禁令.

此外,根据这个问题,如果一个(转发)完全按照标准的要求声明标准容器,算法和仿函数/函数,那么代码应该是完全有效的(如果不是禁止用户自己的声明)该std命名空间),因为实现是不允许添加任何隐藏/默认的模板参数.

我问这个是因为我想最终提交一份有关此问题的缺陷报告.

c++ std forward-declaration defects language-lawyer

10
推荐指数
1
解决办法
746
查看次数

Enum Forward Declaration

我正在尝试为枚举使用正确的前向声明.因此,我搜索了互联网,但我找不到有用的东西.

我在标题中使用:

// Forward declaration
enum myEnumProcessState;
Run Code Online (Sandbox Code Playgroud)

然后我在结构中使用这个枚举:

struct myStruct {
    [...]
    myEnumProcessState osState;
    [...]
};
Run Code Online (Sandbox Code Playgroud)

在另一个标题中:

enum myEnumProcessState {
    eNotRunning,
    eRunning
};
Run Code Online (Sandbox Code Playgroud)

我发现这个类型应该放在enum forward声明中才能被接受.但是,我不知道我应该为流程状态添加哪种"类型".这些不起作用:

enum myEnumProcessState : unsigned int;
enum myEnumProcessState : String; 
Run Code Online (Sandbox Code Playgroud)

我想跳过前方声明,但我的结构正在哭,因为它再也找不到它了......

所以我有点困惑.你知道解决方案吗?

非常感谢 :)

c++ enums forward-declaration

10
推荐指数
1
解决办法
3万
查看次数

前向声明和shared_ptr

我正在尝试重构我的代码,以便我使用前向声明而不是包含大量的标头.我是新手,对boost :: shared_ptr有疑问.

说我有以下界面:

#ifndef I_STARTER_H_
#define I_STARTER_H_

#include <boost/shared_ptr.hpp>

class IStarter
{
public:
    virtual ~IStarter() {};

    virtual operator()() = 0;
};

typedef boost::shared_ptr<IStarter> IStarterPtr;

#endif
Run Code Online (Sandbox Code Playgroud)

然后我在另一个类中有一个函数,它将一个IStarterPtr对象作为参数,比如说:

virtual void addStarter(IStarterPtr starter)
{
    _starter = starter;
}
...
IStarterPtr _starter;
Run Code Online (Sandbox Code Playgroud)

如何在不包含IStarter.h的情况下转发声明IStarterPtr?

我正在使用C++ 98,如果这是相关的.

c++ shared-ptr forward-declaration c++98

10
推荐指数
1
解决办法
2万
查看次数

如何转发声明属于类的模板化类型?

假设我有2个班:

class A
{
public:
  typedef std::shared_ptr<A> Ref;
  ...

private:
  B::Ref _b;
}

class B
{
public:
  typedef std::shared_ptr<B> Ref;
  ...

private:
  A::Ref _a;
}
Run Code Online (Sandbox Code Playgroud)

这显然需要B类和B :: Ref的前向声明.前向声明B很简单,但如何对B :: Ref也这样做?

c++ templates forward-declaration

10
推荐指数
2
解决办法
1432
查看次数

当包装在模板中时,新的不完整类型编译

考虑这个代码,有一个明显的编译错误:(1)

struct A;
struct B {
  B() { new A(); } // error: allocation of incomplete type 'A'
};
Run Code Online (Sandbox Code Playgroud)

使用a unique_ptr也无济于事:(2)

struct A;
struct B {
  B() { std::make_unique<A>(); } // error: due to ~unique_ptr()
};
Run Code Online (Sandbox Code Playgroud)

然后(令我惊讶的是)我发现,这编译:(3)

struct A;
struct B {
  B() { std::make_unique<A>(); }
};
struct A {}; // OK, when a definition is added **below**
Run Code Online (Sandbox Code Playgroud)

然后我检查了,这是否有帮助new- :(4)

struct A;
struct B {
  B() { new A(); } // error: allocation of …
Run Code Online (Sandbox Code Playgroud)

c++ templates forward-declaration

10
推荐指数
1
解决办法
548
查看次数

std :: vector在前向声明的类型上

以下代码似乎在Clang ++和GCC上正常工作:

#include <vector>

class A {
private:
    int i;
    std::vector<A> children;
public:
    A& add();
};

A& A::add() { children.emplace_back(); return children.back(); }

int main() {
    A a;
    A& a2 = a.add();
}
Run Code Online (Sandbox Code Playgroud)

std::vector<A>声明数据成员时,A仍然是不完整的类型.同样在使用std::vector<B>B只向前声明class B;.它应该工作,std::vector因为它只包含一个指针A.

这是保证工作还是未定义的行为?

c++ stl forward-declaration c++11 c++17

10
推荐指数
1
解决办法
1051
查看次数

C编程中前向声明的意义是什么?

我现在通过Zed A. Shaw的"学习C艰难之路"学习C编程.有这个代码(取自他的网站):

#include <stdio.h>
#include <ctype.h>

// forward declarations
int can_print_it(char ch);
void print_letters(char arg[]);

void print_arguments(int argc, char *argv[])
{
    int i = 0;

    for(i = 0; i < argc; i++) {
        print_letters(argv[i]);
    }
}

void print_letters(char arg[])
{
    int i = 0;

    for(i = 0; arg[i] != '\0'; i++) {
        char ch = arg[i];

        if(can_print_it(ch)) {
            printf("'%c' == %d ", ch, ch);
        }
    }

    printf("\n");
}

int can_print_it(char ch)
{
    return isalpha(ch) || isblank(ch);
}


int main(int …
Run Code Online (Sandbox Code Playgroud)

c forward-declaration

10
推荐指数
2
解决办法
2369
查看次数

为什么嵌套类的成员函数不需要完整的类型?

例:

 class A
{
  class B
  {
    A c;//error!A is an incomplete type
    void test() { A b;/*OK,but why?*/ }
  };
};
Run Code Online (Sandbox Code Playgroud)

代码片段对我来说似乎很奇怪,这两种用法有A什么区别?

c++ forward-declaration

10
推荐指数
1
解决办法
520
查看次数

如何创建typedef结构的前向声明

我有test.h一个包含类的.h文件.在这个类中有一个私有方法返回一个我不想做"公共"的类型的指针,但我希望能够将此test.h文件包含在其他源文件中.

通常,在.h文件中使用前向声明很容易:

class Foo;
Run Code Online (Sandbox Code Playgroud)

但问题是这种类型来自一个我无法改变的C文件(因为它是我不维护的其他代码)而且它是一个typedef.

基本上我的意思test.cpp是:

// this type comes from a C file, cannot be changed to struct or class
typedef struct 
{
   int x;
} Foo;

#include "test.h"

static Foo foo;

Foo *Test::private_function()
{
  foo.x = 12;
  return &foo;
}

int Test::compute()
{
   auto *local_foo = private_function();
   return local_foo->x;
}
Run Code Online (Sandbox Code Playgroud)

我的test.h文件是:

#pragma once

struct Foo;

class Test
{
public:
  Test() {}
  int compute();
private:
  Foo *private_function(); …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration

10
推荐指数
1
解决办法
497
查看次数