C++——typedef“内部”模板参数?

Kyl*_*mek 5 c++ templates typedef

想象一下,我有一个这样的模板函数:

template<typename Iterator>
void myfunc(Iterator a, typename Iterator::value_type b)
{ ... }
Run Code Online (Sandbox Code Playgroud)

有没有办法通过为 Iterator::valuetype 声明一个 typedef 来实现同样的事情,我可以在函数签名中使用它?例如,我希望能够做这样的事情:

template<
    typename Iterator,
    typedef Iterator::value_type type>
void myfunc(Iterator a, type b)
{ ... }
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经使用默认模板参数和 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
     ));
     ...
}
Run Code Online (Sandbox Code Playgroud)

...但如果语言支持此类事情,那就太好了。

编辑

我可能应该使用类而不是函数,因为默认参数不是函数的标准。

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));
};
Run Code Online (Sandbox Code Playgroud)

Mr.*_*Ree 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.
}
Run Code Online (Sandbox Code Playgroud)

就我个人而言,在这种情况下,我会选择#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;
}
Run Code Online (Sandbox Code Playgroud)

当然#define是丑陋且有罪的。但读起来非常迟钝的代码也是如此......

ps 为了安全起见,您可能需要添加:

#ifdef  VALUE_TYPE
#error "VALUE_TYPE already defined!"
#endif
Run Code Online (Sandbox Code Playgroud)