C ++ typedef重命名函数

时间:2014-08-15 19:37:52

标签: c++ function templates typedef template-meta-programming

我希望能够使用typedef函数,以便能够将模板元编程用作函数选择器(如下例所示)。我也尝试将函数作为模板参数传递。在这两种情况下都会出现错误,因为函数不是types。我知道如果它们是仿函数,这些方法中的任何一个都会起作用,但我希望能够有一个通用的解决方案。

typedef函数”是否存在实际的方法,但名称不同,我只是不知道?

编辑:

我此时的用例是,我希望能够在使用boost::property_tree::xml_parser::read_xmlboost::property_tree::json_parser::read_json之间进行选择。但它不仅限于这种情况,并且使用成员函数,函数指针或std::function将需要找到所有确切的函数定义并将其复制到正确创建选择器。 / p>

描述用例的更一般方法就像使用typedef double my_float一样,以便稍后可以通过单个编辑更改所有代码。或者,更高级,可以在元组合选择器中定义typedef

void foo1() { /*do stuff*/ }
void foo2() { /*do other stuff*/ }

template <bool SELECT>
struct Selector {
    typedef foo1 foo;
};

template <>
struct Selector<false> {
    typedef foo2 foo;
};

3 个答案:

答案 0 :(得分:6)

又有几个解决方案:

1)C ++ 03解决方案:常量静态函数指针作为类模板的成员

typedef void (*Foo)();

template <bool>
struct Selector
{
    static const Foo foo;
};

template <bool select>
const Foo Selector<select>::foo = foo1;

template <>
const Foo Selector<false>::foo = foo2;

// ...

Selector<true>::foo();
Selector<false>::foo();

Live example.

2)C ++ 11解决方案:类模板的常量静态auto成员

template <bool>
struct Selector
{
    static constexpr auto foo = foo1;
};

template <>
struct Selector<false>
{
    static constexpr auto foo = foo2;
};

// ...

Selector<true>::foo();
Selector<false>::foo();

Live example.

3)C ++ 14解决方案:auto变量模板

template <bool>
constexpr auto foo = nullptr;

template <>
constexpr auto foo<true> = foo1;

template <>
constexpr auto foo<false> = foo2;

// ...

foo<true>();
foo<false>();

Live example.

答案 1 :(得分:3)

我认为您的目标只是根据某些bool选择功能。您可以使用成员函数轻松完成此操作:

template <bool select>
struct selector {
    void operator () () {foo1();}
};

template <>
struct selector <false> {
    void operator () () {foo2();}
};

您当然可以使用int参数和相同的技术在两个以上的函数之间切换。然后,您可以将此struct作为参数传递给任何期望与foo1具有相同签名的函数的函数。 (Live)

答案 2 :(得分:2)

你可以:

1)使用会员功能

void foo1() { std::cout << "foo1\n"; }
void foo2() { std::cout << "foo2\n"; }

template <bool SELECT>
struct Selector {
    void foo() { foo1(); };
};

template <>
struct Selector<false> {
    void foo() { foo2(); };
};

int main() {

  Selector<true> s1t;
  Selector<false> s1f;

  s1t.foo();
  s1f.foo();
}

2)使用通用函数包装器,例如std::function

void foo1() { std::cout << "foo1\n"; }
void foo2() { std::cout << "foo2\n"; }

template <bool SELECT>
struct Selector2 {
    std::function<void(void)> foo = foo1;
};

template <>
struct Selector2<false> {
    std::function<void(void)> foo = foo2;
};

int main() {

  Selector2<true> s2t;
  Selector2<false> s2f;

  s2t.foo();
  s2f.foo();

  return 0;
}

<强> Live demo