使用C++98定义可变参数模板来定义typedef

6

这里的问题相同,只是使用C++98:

我刚刚定义了4个不同的typedef,它们之间的差异很小,我想知道是否有更有效的方法来使用模板。

我的typedef的形式为:typedef Type1 (*pf)(Type2, Type3, ...)

如何将此typedef转换为模板?

Type1是必需的。

我手动编写:

typedef int (*pf)(int)
typedef bool (*pf)()
typedef char (*pf)(bool, int)

我正在寻找类似以下这种的东西:
template <Type T1,Type...Rest>
typedef T1 (*pf)(Type...Rest)

这正确吗?


3
可变参数模板是C++11的一个特性。 - Yuushi
@Yuushi 好的,听起来就是这个答案。请将其作为答案发布。对于搜索的人来说仍然是一个有效的问题。 - Bob
1个回答

4
你可以使用Boost.Preprocessor在C++98中模拟可变参数模板。实际上,在幕后所做的是预处理器为不同数量参数的所有特化写入模板。现在,您可以在varadic<...>::type中使用typedef,最多有256个模板参数。
对于模板,这并不是一个问题,因为只有实例化的模板进入二进制文件,但对于非模板实体,这可能导致代码膨胀。
#include <iostream>
#include <boost/preprocessor/config/limits.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>

// Macro to generate specializations
#define MAKE_VARIADIC(Z, N, _)                                          \
  template <                                                            \
    typename R                                                          \
    BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename T)                   \
      >                                                                 \
  struct variadic < R BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, T) >        \
  {                                                                     \
    typedef R (*type)(BOOST_PP_ENUM_PARAMS_Z(Z, N, T));                 \
  };

// Declare variadic struct with maximum number of parameters
template <
  typename R
  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_LIMIT_ITERATION, typename T, = void BOOST_PP_INTERCEPT)
    >
struct variadic;

// Repeat macro to create all specializations
BOOST_PP_REPEAT(BOOST_PP_LIMIT_ITERATION, MAKE_VARIADIC, nil)


// Function to print what was derived
template < typename T >
void print_T()
{
  std::cout << __PRETTY_FUNCTION__ << '\n';
}

// Test
int main ()
{
  print_T< variadic<int, double, float>::type > ();
}

在Wandbox上的演示


然而,使用C++11的别名模板会更加方便处理这种情况,在2017年,标准定稿后六年,没有理由不切换到C++11。仍在使用C++98就像仍在使用Windows XP一样过时。

#include <iostream>

template <typename R, typename ... Args>
using pf = R(*)(Args...);

// Function to print what was derived
template < typename T >
void print_T()
{
  std::cout << __PRETTY_FUNCTION__ << '\n';
}

// Test
int main ()
{
  print_T< pf<int, double, float> > ();
}

在 Wandbox 上的演示


没错,但仍然有人可能还保留着从以前那个时代获得的“复古电脑”,他们可能出于兴趣或其他原因将其作为爱好进行“修理”。由于操作系统和应用程序的版本限制,他们可能只能使用特定的OS - Applications\Programs版本。虽然很少见到C++98的问题出现,但出于“传统”或“历史”原因,我仍然认为这是有益的。我还记得在高中计算机课上同时使用Visual Basic和C++,当时我们用的是Windows 95/98机器,因为Windows XP都还未发布。那时候我还精通DOS和Q-Basic呢!我已经给你点了赞 :) - Francis Cugler
2
@FrancisCugler:有一个RetroComputing SE网站。而且由于C++98来自另一个世纪,我同意它符合复古的标准。 - MSalters
同时考虑那些被困在无法升级的旧系统上,被迫使用旧版 C 98 编译器的嵌入式开发人员... - BenHero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接