在Xcode中是否有与__COUNTER__等效的功能?

3
我正在将一个项目从Linux迁移到Xcode,遇到了“版本”问题... 我需要在编译时为我的动态内容提供唯一标识符,在Linux上我使用了__ COUNTER__预处理器,但是似乎Xcode中使用的gcc 4.2还不知道__ COUNTER__... 所以,我想知道我能做什么来解决这个问题?我可以通过使用macports.org之类的软件升级GCC到4.3(它理解__ COUNTER__),但我对OSX很陌生,对Linux也不是很擅长 =[或者找到另一种方法来实现这一点,在这种情况下,是为函数/变量提供唯一标识符的方法。我尝试使用__ LINE__,但几天后,你会发现在不同文件的同一行上声明的东西,并且玩弄这些东西并不那么有效率...任何帮助都将不胜感激!谢谢,Jonathan

1
你试图解决什么问题?我从未真正看到过需要唯一标识符的计数器宏在单个翻译单位以外有好的用途。 - James McNellis
我需要对项目中使用的所有类进行分类,以便这些类可以在工厂内部动态创建。为此,我唯一想到的解决方案是声明一个值类变量,在其初始化时将新的类声明添加到工厂列表中。这是完全动态的,程序员只需使用预处理器声明类即可自动进行分类,并且可以在需要时立即使用。 - Jonathan
你觉得 ((md5sum(_FILE_)+LINE) 怎么样?(如果你愿意,可以使用你最喜欢的字符串哈希算法来替换md5sum) - Jeremy Friesner
2个回答

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")。

我们将此解决方案用作boost::any的替代方案,我们通过SDK提供boost::any(因此无法使用boost,因为这将要求我们的用户安装boost,或者我们要发送boost的部分内容,这可能会导致安装了不同版本的boost的用户之间发生冲突)。它不像boost::any那样自动化,因为它需要手动注册支持的类型(在这方面更接近于boost::variant),但不需要我们的SDK用户启用RTTI,并且可以在模块边界上可移植使用(我不确定是否可以依赖RTTI在不同编译器、设置和模块之间产生相同的信息-我怀疑)。

现在,您可以根据需要使用这些与类型相关联的字符串ID。一个例子是将创建函数映射到这些字符串ID,以便您可以通过factory::create("std::string")创建std::string的实例。请注意,这只是演示目的的假设情况,因为使用工厂来创建std::string会相当奇怪。


0

@stinky472: 我使用了一个与你上面写的代码类似的代码...

我的问题是,我使用宏声明了一个项目的命名空间,因此,如果有类c在a :: b :: c中,就有了类的完整名称。
我所做的是改变我的代码,不再依赖于命名空间本身,而是在类宏定义时添加一个新的参数来告诉它使用的命名空间,如:

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

};

我的计数器问题在于命名空间被用于许多类中,从而在命名空间宏中创建相同的变量名,通过以上的新方法,我不再需要计数器...

感谢您的帮助,
Jonathan


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接