将类型说明符传递给模板函数

时间:2017-09-22 10:12:19

标签: c++ templates

我正在尝试以

的形式替换宏
UPDATE

我如何编写一个等效的模板函数,该函数使用类型说明符来调用#define FOO(object, typeSpecifier) object.f<typeSpecifier>()

即。将带有说明符object.f<typeSpecifier>()和对象Mytype的自定义类型传递给object的{​​{1}}

编辑在做出答案之前,简化代码中存在一些误导性错误。即宏取代的函数名称相同,这是错误的

3 个答案:

答案 0 :(得分:1)

函数不能将类型作为参数,因此您无法使用函数:

f(foo, int); // Not possible

您可以打包类型:

template <typename> struct tag{};

f(foo, tag<int>{});

但是你必须改变调用代码。

因此,如果您不想更改呼叫站点,则必须保留宏。

如果您可以将呼叫网站更改为f<int>(foo);,则可以使用:

template <typename T, typename Object>
decltype(auto) f(Object&& object)
{
    return std::forward<Object>(object).template <T>()
}

答案 1 :(得分:0)

您可以依赖template argument deduction之类的:

template<typename T, typename U>
void f(T& object, const U& typeSpecifier) {
    object.template f<U>();
}

在这种情况下,您可以调用f功能,例如如下:

f(foo, std::string{});

正如下面的评论所指出的,我的示例仅适用于默认的可构造类型,因此使用accepted answer中显示的帮助器类型是一种更好的方法:

template<typename>
struct type {
};

template<typename T, typename U>
void f(T& object, type<U>) {
    object.template f<U>();
}

使用

int main() {
    MyType foo;
    f(foo, type<std::string>());
}

答案 2 :(得分:0)

零开销方式是使用标签分派:

#include <iostream>

template<class Type> struct tag {};

template<class Object, class Tag>
decltype(auto) f(Object&& o, tag<Tag>)
{
    return o.template f<Tag>();
}


struct X {
    template<class T> auto f() {
        return T(0);
    }

};

template<> auto X::f<int>() {
    std::cout << "an int" << std::endl;
    return 0;
}

template<> auto X::f<double>() {
    std::cout << "a double" << std::endl;
    return 0;
}


int main()
{
    X x;

    f(x, tag<int>());
    f(x, tag<double>());
}