【问题标题】:__COUNTER__ equivalent on Xcode?Xcode 上的 __COUNTER__ 等价物?
【发布时间】:2010-06-28 02:18:53
【问题描述】:

我正在将一个项目从 Linux 迁移到 Xcode,但遇到了“版本”问题..

我需要在编译时为我的动态内容创建一个唯一标识符,在 linux 上我使用的是 __ COUNTER__ 预处理器,但 Xcode 中使用的 gcc 4.2 似乎还不知道 __ COUNTER__...
所以,我想知道我能做些什么来解决这个问题?
我可以通过使用 macports.org 或类似的东西将 GCC 升级到 4.3(它理解 __ COUNTER__)...我在 OSX 上非常菜鸟,在 linux 上不太好 =[
或者找到另一种方法来实现这一点,在这种情况下,一种方法给函数/变量一个唯一的标识符。我尝试使用 __ LINE__ 但几天后,您最终会在不同文件的同一行上声明内容,并且使用它并没有那么高产......

感谢任何帮助!

谢谢,
乔纳森

【问题讨论】:

  • 您要解决什么问题?我从来没有真正看到需要单个翻译单元之外的唯一标识符的计数器宏有什么好的用途。
  • 我需要对项目中使用的所有类进行编目,因此可以在工厂内动态创建这些类,因此,我得到的唯一解决方案是声明一个值类变量它的初始化会将这个新的类声明添加到工厂列表中,这都是动态的,使用 lib 的程序员只需使用预处理器声明该类,它将被自动编目并可以在之后动态使用
  • 怎么样 ((md5sum(_FILE_)+__LINE__) ?(如果需要,请填写您最喜欢的字符串哈希码算法,而不是 md5sum)

标签: c++ xcode gcc uniqueidentifier counter


【解决方案1】:

我需要对所有使用的类进行编目 一个项目,所以这些类可以 从内部动态创建 工厂 [...]

没有使用 RTTI(如果你被允许这样做,这不是一个坏主意; boost::any 这样做),只使用字符串作为类名怎么样?您可以通过宏检索它。

#include <iostream>
#include <string>
using namespace std;

template <class T>
const char* my_type_id()
{
    return "Unknown";
}

#define REGISTER_TYPE(some_type)            \
    template <> inline                      \
    const char* my_type_id<some_type>()     \
    {                                       \
        return #some_type;                  \
    }

REGISTER_TYPE(int)
REGISTER_TYPE(std::string)

int main()
{
    // displays "int"
    cout << my_type_id<int>() << endl;

    // displays "std::string"
    cout << my_type_id<string>() << endl;

    // displays "Unknown" - we haven't registered char
    cout << my_type_id<char>() << endl;
}

这种方法的好处是您不必担心使用这种方法跨翻译单元或模块的问题。唯一需要注意的是名称冲突,在这种情况下,您可以指定一个命名空间来帮助避免它们(“std::string”而不是简单的“string”,例如)。

我们将此解决方案用作我们通过 SDK 提供的 boost::any 的替代方案(因此不能使用 boost,因为它需要我们的用户安装 boost 或让我们运送部分 boost 在这种情况下这可能会导致安装了不同版本的 boost 的用户发生冲突)。它不像 boost::any 那样自动,因为它需要手动注册支持的类型(在这方面更接近 boost::variant),但不需要我们的 SDK 用户启用 RTTI 并且可以跨模块边界可移植地工作(I'我不确定是否可以依赖 RTTI 在不同的编译器、设置和模块中生成相同的信息 - 我对此表示怀疑)。

现在您可以随意使用这些类型相关的字符串 ID。一个示例是使用它将创建函数映射到这些字符串 ID,以便您可以创建 std::string 的实例,例如,通过 factory::create("std::string");请注意,这是一个仅用于演示目的的假设案例,因为使用工厂创建 std::string 会很奇怪。

【讨论】:

    【解决方案2】:

    @stinky472:我用的代码和你上面写的差不多……

    我的问题是我使用宏来声明项目的命名空间,因此,有了类的全名,就像类 c 在 a::b::c 中一样。
    我所做的是将我的代码更改为不依赖命名空间本身,而是在类宏声明中添加一个新参数来告诉它正在使用什么命名空间,例如:

    newclass(a::b, c): public d{

    };

    我对计数器的问题是命名空间被用于许多类,因此,在命名空间宏中创建相同的变量名,并且通过使用上面的新方法,我不再需要计数器了......

    感谢您的帮助,
    乔纳森

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      相关资源
      最近更新 更多