C++ 流日志 Objective-C 对象

标签 c++ iostream objective-c++ ostream

我正在尝试编写一个 C++ 流记录器,它也能够打印 Objective-C++ 变量。 问题是我无法编译它,因为在调用 obj-c 方法时进行模板类型检查,该方法为我提供了对象的描述。

我想知道一些如何实现这一目标的想法。

谢谢

#ifdef __OBJC__
//for operator<< on obj-c objects
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

//SFINAE to get whether we have a obj-c class or not
template<class T> struct IsObjectiveCClass {
    using yesT = char (&)[10];
    using noT = char (&)[1];
    static yesT choose(id);
    static noT choose(...);
    static T make();
    enum { value = sizeof(choose(make())) == sizeof(yesT) };
};
#endif

class Logger {

...


        template <typename T>
        Logger &operator <<(T data) {
#if __OBJC__

            if (IsObjectiveCClass<T>::value) {
                ... How to cast (data to obj) without errors? ...    
                stream->ts << [[obj description] UTF8String];
            } else {
#endif
                stream->ts << data;
#if __OBJC__
            }
#endif
        }

最佳答案

尝试这样的事情

template<typename T, typename V = bool>
struct is_objc_class : std::false_type { };

template<typename T>
struct is_objc_class<T,
typename std::enable_if<std::is_convertible<T, id>::value, bool>::type
> : std::true_type { };

template <
class T,
class = typename std::enable_if<is_objc_class<T>::value>::type
>
std::ostream& operator<< (std::ostream& stream, T const & t) {
    stream << [[t description] UTF8String];
    return stream;
}

struct Logger
{
    Logger(std::ostream &s):stream(s){}
    std::ostream &stream;

    // for objc class
    template <class T>
    typename std::enable_if<is_objc_class<T>::value, Logger&>::type
    operator<< (T const & t) {
        stream << [[t description] UTF8String];
        return *this;
    }

    // for everything else
    template <class T>
    typename std::enable_if<!is_objc_class<T>::value, Logger &>::type
    operator<< (T const & t) {
        stream << t;
        return *this;
    }
};

int main(int argc, char *argv[])
{
    std::cout << std::boolalpha
    << is_objc_class<id>::value << std::endl
    << is_objc_class<int>::value << std::endl
    << is_objc_class<NSString *>::value << std::endl
    << @"test" << std::endl
    << @[@1] << std::endl
    ;

    Logger l(std::cout);

    l << @"test" << "test2" << @1 << 1;
}

关于C++ 流日志 Objective-C 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23206800/

相关文章:

c++ - 如何获取对象的当前引用计数?

C++控制台屏幕大小

c++ - 尝试从 cin 获取输入时陷入循环

c++ - 抑制 pcl 注册的 cout 输出

c++ - 对象 C 错误 : "expected unqualified-id before class pointer"

ios - Objective-C++ : Call Objective C method from C++

objective-c - Cocoa 中的分布式对象

c++ - 如何为每个派生类存储一个可以从基类访问的魔数(Magic Number)?

c++ - const int*& 与 typedef int* IntPtr

C++ - JSON::Value 在函数参数中用作引用