【问题标题】:Member-function templates and overloading operator() in C++C++ 中的成员函数模板和重载 operator()
【发布时间】:2011-01-03 15:53:52
【问题描述】:

以下代码 sn-p 对我有用:

class Foo {
public:
    template <class T> T& get () { ... }
};

Foo foo;
foo.get<int>() = ...;

但是,下面的代码 sn-p 对我不起作用:

class Foo {
public:
    template <class T> T& operator() () { ... }
};

Foo foo;
foo<int>() = ...;

错误是:

expected primary-expression before '>' token
expected primary expression before ')' token

两个错误都指向foo&lt;int&gt;()

为什么这不起作用,是否有可能解决这个问题?

【问题讨论】:

  • 您的模板operator() 非常不可用,因为它的实例化只会在返回值上过载。继续使用get 名称或类似名称。
  • 它不是不可用的(尽管它可能不是更可取的)。请参阅下面的答案。
  • 为什么要模板化函数而不是整个类?
  • @Zac,因为我不需要。我将它用于实体系统之类的东西,所以我可以这样做:Entity entity = entitySystem.createEntity(); entitySystem.addTrait(entity, Position::id()); ... std::cout &lt;&lt; entity.get&lt;Position&gt;().x;

标签: c++ templates operator-overloading


【解决方案1】:

如果您需要显式指定模板参数,则需要使用operator 语法:

foo.operator()<int>()

没有任何方法可以使用函数调用语法来指定参数。如果你不能从函数的参数中推断出模板参数,那么使用成员函数比使用运算符重载要好。

【讨论】:

    【解决方案2】:

    问题是你的模板参数列表放错了地方;就好像您正在尝试使用带有模板参数 int 的名为 foo 的对象或函数,但实际上您希望模板参数列表位于 operator() 上。

    不幸的是(至少可以说是这样),运营商无法解决这个问题。您必须将它们称为完整功能:

    class Foo {
    public:
        template <class T> T& operator()() { ... }
    };
    
    Foo foo;
    foo.operator()<int> = ...;
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您也可以这样做

      class Foo {
      public:
        template <class T> operator T&() { ... }
      };
      

      然后它会根据“返回”类型自动调用正确的函数:

      Foo foo;
      int i=foo;
      

      我知道大多数人不喜欢这样,因为被调用的函数取决于返回类型,但我发现它是一个很好的“技巧”,通常可以清理语法。

      【讨论】:

      • 额外警告:很容易意外地用非预期类型实例化该“转换”方法。
      • 我认为这是一个使代码异常复杂的技巧。您已经为 any 类型提供了一个转换运算符...它将在最不可能的地方打击您,您可能既没有预料到也没有意识到!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      相关资源
      最近更新 更多