C ++函数结构,无论模板类型如何

时间:2016-11-15 16:07:23

标签: c++ templates

我有一组函数可以处理模板化的类,但不依赖于类的模板化部分。

模板化函数并允许它推断出类型会起作用,但会编译成多个函数。

#include <iostream>

template<typename T>
struct MyStruct {
    int a;
    T b;
};


bool isLess(MyStruct& lhs, MyStruct& rhs) {
    return lhs.a < rhs.a;
}


int main(int argc, char const *argv[])
{
    MyStruct<int> x {123, 456};
    MyStruct<int> y {789, 123};

    std::cout << isLess(x, y) << std::endl;

    return 0;
}

有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:12)

重构不依赖于另一个类中的T的字段。让MyStruct<T>继承自:

struct MyStructBase
{
    int a;
};

template<typename T>
struct MyStruct : MyStructBase 
{
    T b;
};

bool isLess(MyStructBase& lhs, MyStructBase& rhs) {
    return lhs.a < rhs.a;
}

int main(int argc, char const *argv[])
{
    MyStruct<int> x {123, 456};
    MyStruct<int> y {789, 123};

    std::cout << isLess(x, y) << std::endl;

    return 0;
}

答案 1 :(得分:9)

您可以使用继承:

struct MyStructBase {
    int a;
};

template<typename T>
struct MyStruct : public MyStructBase {
    T b;
};


bool isLess(MyStructBase& lhs, MyStructBase& rhs) {
    return lhs.a < rhs.a;
}

答案 2 :(得分:1)

我会这样做:

template<typename L, typename R>
auto isLess(L&& lhs, R&& rhs) -> decltype(std::declval<L>().a < std::declval<R>().a) {
    return std::forward<L>(lhs).a < std::forward<R>(rhs).a;
}

无论您的类型之间的关系如何,这都将起作用,并且不会编译为多个函数(参见最后一段)。它将允许任何成员a的类型低于可比类型。

  

模板化函数并允许它推导出类型会起作用,但会编译成多个函数。

糟糕的猜测。它甚至比那更好,它将编译为根本没有功能,因为任何理智的编译器(甚至msvc)都将完全内联函数。