【问题标题】:C++ -- typedef "inside" template arguments?C++——typedef“内部”模板参数?
【发布时间】:2010-03-29 01:39:20
【问题描述】:

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

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 中。
  • 我也修正了你的其他遗漏类型名的地方。希望你不介意。

标签: c++ templates typedef


【解决方案1】:

您正在寻找要在模板化函数定义中使用的模板化 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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 哦,在我的示例中缺少类型名是一个错误,感谢您发现它。然而,这不是我要回答的问题。我真正想要的是通过为 b 使用 typedef 来减少函数签名的冗长。
    • @redmoskito:我不确定我是否理解您想要完成的任务。您的第二个代码 sn-p 比第一个长,第三个代码比较庞大。只看冗长,第一个是最好的选择。据我所知,这也是您唯一的选择。无法完成您在第二个 sn-p 和第三个 sn-p 中显示的内容,虽然在 C++0x 中是允许的,但在 C++03 中无效(只有类模板可以在 C++ 中具有默认模板参数03).
    • 您可能最终会变得不那么冗长,但 IMO 从函数签名中删除迭代器的显式类型会使其不太清晰,除非您选择了比“类型”更好的措辞
    • @redmoskito:我想,如果你有多个参数都是相同的依赖类型,它可以缩短声明,所以我可以看到你想要完成什么。不过,我仍然认为没有办法实现它。
    • @James 显然这是一个微不足道的例子。考虑一下我有 10 个类型为 Iterator::value_type 的参数的情况——我的第二个代码中的技术被剪断会短得多。第三个示例有更多代码,但它实现了我正在寻找的签名的简洁性。这是针对库代码的,所以如果接口被简化,更详细的实现是可以的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2015-03-17
    相关资源
    最近更新 更多