function traits

本文介绍了一种改进的 C++ function_traits 实现,该实现能够解析不同类型的函数签名,并提供有关函数返回类型、参数数量及类型等信息。通过模板元编程技术,此 function_traits 可用于多种场景,如 C++ 委托机制中。
我写的一个简单的 function traits,功能比 boost::unary_traits 和 boost::binary_traits 强,下面是其实现和一个简单的demo。这个function traits已经被我用在了一个C++ delegate 上,不过做了一些修改,但事实证明这个function_traits很有用。

template <typename Operation>
struct function_traits;

// no argument

// function type
template <typename R>
struct function_traits<R ()>
{
    // this is function type, not function pointer type
    typedef R (function_type)();
    typedef R result_type;
    enum{argument_count = 0};
    enum{ismemfun = false};
};

// function pointer type
template <typename R>
struct function_traits<R (*)()>
{
    typedef R (function_type)();
    typedef R result_type;
    enum{argument_count = 0};
    enum{ismemfun = false};
};

// pointer to member function
template <typename C, typename R>
struct function_traits<R (C::*)()>
{
    typedef C class_type;
    typedef R result_type;
    enum{argument_count = 0};
    enum{ismemfun = true};
};

// one argument
template <typename R, typename A>
struct function_traits<R (A)>
{
    typedef R (function_type)(A);
    typedef R result_type;
    enum{argument_count = 1};
    typedef A first_argument_type;
};

template <typename R, typename A>
struct function_traits<R (*)(A)>
{
    typedef R (function_type)(A);
    typedef R result_type;
    enum{argument_count = 1};
    typedef A first_argument_type;
};

template <typename C, typename R, typename A>
struct function_traits<R (C::*)(A)>
{
    typedef C class_type;
    typedef R result_type;
    enum{argument_count = 1};
    enum{ismemfun = true};
    typedef A first_argument_type;
};

// two arguments
template <typename R, typename A, typename B>
struct function_traits<R (A, B)>
{
    typedef R (function_type)(A);
    typedef R result_type;
    enum{argument_count = 2};
    typedef A first_argument_type;
    typedef B second_argument_type;
};

template <typename R, typename A, typename B>
struct function_traits<R (*)(A, B)>
{
    typedef R (function_type)(A);
    typedef R result_type;
    enum{argument_count = 2};
    typedef A first_argument_type;
    typedef B second_argument_type;
};

template <typename C, typename R, typename A, typename B>
struct function_traits<R (C::*)(A, B)>
{
    typedef C class_type;
    typedef R result_type;
    enum{argument_count = 2};
    enum{ismemfun = true};
    typedef A first_argument_type;
    typedef B second_argument_type;
};

//-----------------------------------------------------------

typedef int (*FUNC0)();
typedef int (*FUNC1)(int);
typedef int (*FUNC2)(int, char);

class AClass{
public:
    void speak0();
    int speak1(int);
    int speak2(int, char);

    typedef void (*tspeak0)();
    typedef int (*tspeak1)(int);
    typedef int (*tspeak2)(int, char);
};

#include <iostream>
#include <typeinfo>

int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;
    cout << typeid(function_traits<int (char)>::result_type).name() << '/n';
    cout << typeid(function_traits<int (*)(char)>::result_type).name() << '/n';
    cout << typeid(function_traits<int (AClass::*)(int)>::class_type).name() << '/n';

    //    cout << typeid(function_traits<FUNC2>::first_argument_type).name() << '/n';
//    cout << typeid(function_traits<FUNC2>::second_argument_type).name() << '/n';

//    cout << typeid(function_traits<int (int ***)>::first_argument_type).name() << '/n';
    return 0;
}
 
在编程语言和框架中,**traits** 是一种用于定义对象行为的机制,它提供了一种灵活的方式来组合和复用代码。与传统的类继承不同,traits 强调的是“组合”而非“继承”,允许开发者将一组方法定义为可重用的模块,并在多个类中使用这些方法的实现。 Traits 的概念最早出现在 **Smalltalk** 社区中,但真正将其推广的是 **PHP** 和 **Scala** 等语言。Traits 的设计目的是解决多重继承带来的复杂性问题,同时保留代码复用的能力。 ### Traits 在不同编程语言中的实现 #### 1. **PHP 中的 Traits** PHP 在 5.4 版本引入了 traits,用于解决类的多重继承问题。Traits 允许开发者在类中水平复用方法,而不是通过继承来实现代码共享。例如: ```php trait HelloWorld { public function sayHello() { echo 'Hello World'; } } class Myclass { use HelloWorld; } $obj = new Myclass(); $obj->sayHello(); // 输出 Hello World ``` PHP 的 traits 支持方法冲突解决机制,开发者可以通过 `insteadof` 和 `as` 关键字明确指定使用哪个 trait 的方法[^3]。 #### 2. **Scala 中的 Traits** 在 Scala 中,traits 类似于 Java 的接口(interface),但功能更强大。它们不仅可以包含抽象方法,还可以包含具体实现。Traits 可以被类或对象混入(mixin),从而扩展其行为。例如: ```scala trait Greeter { def greet(name: String): Unit = println(s"Hello, $name") } class FrenchGreeter extends Greeter { override def greet(name: String): Unit = println(s"Bonjour, $name") } val greeter = new FrenchGreeter() greeter.greet("Alice") // 输出 Bonjour, Alice ``` Scala 的 traits 支持线性化(linearization)机制,确保在多个 traits 被混入时,方法调用的顺序是可预测的[^4]。 #### 3. **Rust 中的 Traits** Rust 的 traits 类似于接口,用于定义类型的行为。它们允许为类型定义共享的方法集,并支持泛型编程。例如: ```rust trait Summary { fn summarize(&self) -> String; } struct NewsArticle { headline: String, location: String, author: String, content: String, } impl Summary for NewsArticle { fn summarize(&self) -> String { format!("{}, by {} ({})", self.headline, self.author, self.location) } } let article = NewsArticle { headline: String::from("Rust Language"), location: String::from("Worldwide"), author: String::from("Rust Team"), content: String::from("Rust continues to gain popularity..."), }; println!("{}", article.summarize()); // 输出 "Rust Language, by Rust Team (Worldwide)" ``` Rust 的 traits 支持默认实现、trait bounds 以及泛型约束,是 Rust 实现多态的重要机制之一[^5]。 ### Traits 与 Mixins、Interfaces 的区别 - **Mixins**:Mixins 是一种通过多重继承实现的代码复用机制,通常用于动态语言(如 Ruby 或 Python)。Mixins 与 traits 的主要区别在于,mixins 通常依赖于类的继承结构,而 traits 是一种更轻量、更模块化的组合方式。 - **Interfaces**:接口(interface)定义了类必须实现的方法,但不提供具体实现。Java 8 引入了默认方法(default methods),使得接口可以包含部分实现,这在功能上与 traits 有些相似。然而,traits 通常支持更复杂的组合逻辑,例如冲突解决和混入顺序控制。 ### Traits 的优缺点 #### 优点: - 提高代码复用性,避免了多重继承的复杂性。 - 支持更灵活的行为组合,适合构建模块化系统。 - 提供清晰的命名冲突解决方案。 #### 缺点: - 可能增加代码的复杂性,尤其是在多个 traits 被混入的情况下。 - 不同语言对 traits 的实现方式不同,学习曲线可能较高。 ### 应用场景 Traits 在现代编程语言中广泛用于构建可扩展的库和框架。例如: - **PHP 的 Laravel 框架**:使用 traits 来实现模型的可复用行为,如软删除、时间戳等。 - **Scala 的 Akka 框架**:利用 traits 实现 actor 的行为组合。 - **Rust 的标准库**:大量使用 traits 来定义类型的行为,如 `Iterator`、`Clone` 等。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值