【问题标题】:About C++ template and operators关于 C++ 模板和运算符
【发布时间】:2010-10-21 17:15:53
【问题描述】:

经过一些尝试和很多错误,我发现它对模板运算符不是很有用。举个例子:

class TemplateClass
{
  //Generalized template
  template<TType>
  TType& operator[](const std::string& key)
  {
    return TType;
  }
  //Specialized template for int
  template<>
  int& operator[]<int>(const std::string& key)
  {
    return 5;
  }
  //Specialized template for char
  template<>
  char& operator[]<char>(const std::string& key)
  {
    return 'a';
  }
}
int main()
{
  TemplateClass test;
  //this will not match the generalized template.
  test["test without template will fail"]; 
  //this is not how you call an operator with template.
  test<char>["test with template will fail"];
  //this works!
  test.operator[]<int>["test will work like this"];
  return 0;
}

因此,使用模板制作运算符非常难看(除非您很冗长,而且真的是谁?)这就是为什么我一直使用函数“get”来代替运算符的原因。我的问题是为什么丑?为什么需要包含操作符关键字。我的猜测是,它与转换运算符以不使用括号来接受参数的一些后端魔法有关,有没有办法解决这个问题?提前致谢。

【问题讨论】:

  • 反复试验,哦,如果你读一本书,你可以节省的时间......
  • 请注意,如果运算符采用模板参数类型的参数(如 template int & operator[](const T & key) 则编译器可以从参数中推断出模板参数当你调用它时你通过了。
  • 我的问题是WTF?你为什么还要尝试这个?应避免专门化(如果可以),并且仅当编译器可以通过模板参数推导规则找出模板参数时,才应使用模板化运算符。至于一本C++模板相关的书,我可以推荐《C++ Templates -- The Complete Guide》。
  • 您将运算符重载与函数模板特化结合使用。那是evilsquared。不要那样做。
  • @sellibitze:它必须是模板专业化,愚蠢,因为你不能重载返回类型。 ;-)

标签: c++ templates operators


【解决方案1】:

这不是模板的具体问题。这是一个语法问题。您所做的很奇怪,因为您只是更改了返回类型。如果您更改了运算符参数,则不必显式提供模板的类型。由于您确实需要提供类型,因此您需要显式调用运算符来应用参数,因为这是唯一的方法。

查看grammar 了解完整详情。

【讨论】:

  • 这个。区分 &lt;&gt; 模板参数和比较运算符的语法很粗糙。
  • 我只能想象这是一种虐待狂。
  • 你说得对,这只是一个练习,我确实在将代码输入键盘之前寻找了一些答案。该项目类似于系统目录;给定一个字符串路径和数据,在内存中创建路径并存储数据。我的方法是创建一个包含两棵树的类,一棵用于给定级别的数据,另一棵用于比当前目录更深的目录。一个简单的递归练习。我可以很容易地拥有函数“getData”和“getDir”,但由于这是一个练习,我想尝试做一些更精细的东西。那好吧。 :?
  • @Jericho Kain:像这样以“聪明”的方式做事会导致糟糕的代码。在实践中永远不要这样做。让事情变得简单明了。这对每个人都更好。
【解决方案2】:

返回类型不能用于重载决议。您的 operator[] 声明的签名的唯一区别在于它们的返回类型,因此一旦您拥有其中两个,编译器就没有希望消除您的调用test["test without template will fail"];

【讨论】:

    【解决方案3】:

    是的,模板参数推导不适用于简单的函数返回类型。然而,模板运算符重载确实很有用,并且可以以一些非常棒的方式应用。

    下面是来自boost::phoenix的代码示例。

    for_each(c.begin(), c.end(),
        if_(arg1 % 2 == 1)
        [
            cout << arg1 << ' '
        ]
    );
    

    您可能会理解,这是一种打印出容器中所有奇数元素的简单方法。有点神奇。

    【讨论】:

      猜你喜欢
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 2010-12-27
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多