C++ -- 模板参数中使用typedef?

5

假设我有一个像这样的模板函数:

template<typename Iterator>
void myfunc(Iterator a, typename Iterator::value_type b)
{ ... }

有没有一种方法可以通过声明 Iterator::valuetype 的 typedef 来实现相同的功能,以便我可以在函数签名中使用它?例如,我希望能够像这样做:

template<
    typename Iterator,
    typedef Iterator::value_type type>
void myfunc(Iterator a, type b)
{ ... }

目前为止,我一直使用默认的模板参数和Boost概念检查来确保始终使用默认值:

template<
    typename Iterator,
    typename type = typename Iterator::value_type >
void myfunc(Iterator a, type b)
{
     BOOST_STATIC_ASSERT((
         boost::is_same<
             typename Iterator::value_type, 
             type
         >::value
     ));
     ...
}

......但如果语言支持这种类型的功能,那就太好了。

编辑

我可能应该使用类而不是函数,因为默认参数在函数中并不常见。

template<
    typename T,
    typename V = typename T::value_type>
class A : public B<T, V>  
{
    BOOST_STATIC_ASSERT((boost::is_same<typename T::value_Type, V>::type));
};

关于注释:函数模板的默认模板参数是一个扩展。它们不在c++03中。 - Johannes Schaub - litb
我也修复了你遗漏的typename。希望你不介意。 - Johannes Schaub - litb
2个回答

2

在参数列表中,您可以使用typename

template <typename Iterator>
void myfunc(Iterator a, typename Iterator::value_type b)
{ 
}

哦,缺少typename是我例子中的一个错误,感谢你发现了这个问题。然而,这不是我想回答的问题。我真正想做的是通过使用b的typedef使函数签名更简洁。 - Kyle Simek
@redmoskito:我不确定我理解你想要实现什么。你的第二个代码片段比第一个更长,第三个则相对巨大。从冗长程度来看,第一个是最好的选择。据我所知,这也是你唯一的选择。无法实现你在第二个片段和第三个片段中展示的内容,虽然在C++0x中允许,但在C++03中无效(只有类模板可以在C++03中具有默认模板参数)。 - James McNellis
在编程中,你可能会尝试减少冗余代码,但我认为如果你从函数签名中删除迭代器的显式类型,除非你选择更好的措辞,否则这将使它变得不够清晰。 - hhafez
2
@redmoskito:我想,如果您有多个参数都是相同的依赖类型,那么它可以缩短声明,所以我可以理解您试图实现什么。但我仍然认为没有办法实现它。 - James McNellis
@James 显然这只是一个微不足道的例子。考虑一下我有10个Iterator::value_type类型的参数的情况——我第二段代码片段中的技巧会更短。第三个例子有更多的代码,但它实现了我所寻求的简洁签名。这是用于库代码的,因此如果接口被简化,更冗长的实现也可以接受。 - Kyle Simek
显示剩余2条评论

2
你正在寻找一个模板typedef以在模板函数定义中使用。我认为你不能这样做...
你可以有一个带有静态函数和typedef的模板类...但使用它会变得很丑陋:
template<typename Iterator>
class arbitraryname
{
public:
  typedef typename Iterator::value_type  value;

  static void myfunc( Iterator a, value b )
  {
    value c = b;
    cout << "Test" << c << endl;    
  }
};

struct Foo
{
  typedef int value_type;
};

int main()
{
  Foo f;
  myfunc<Foo>(f,2); // Old way.
  arbitraryname<Foo>::myfunc(f,3); // With templated class.
}

就我个人而言,在这种情况下,我会选择使用#define...

#define VALUE_TYPE  typename Iterator::value_type
template<typename Iterator>
void myfunc(Iterator a, VALUE_TYPE b)
#undef VALUE_TYPE
{
  typedef typename Iterator::value_type  bar;
  bar z = b;
  cout << "Test" << z << endl;
}

当然,#define很丑陋,也是有罪的。但同样难以阅读的代码也是如此…

附言:为了保险起见,您可能需要添加:

#ifdef  VALUE_TYPE
#error "VALUE_TYPE already defined!"
#endif

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