【问题标题】:C++ template overload callC++ 模板重载调用
【发布时间】:2017-03-23 12:10:15
【问题描述】:

我正在尝试实现一种执行模式,该模式采用任何功能并使用自己的条件/准备来执行它。尽管这是一件有用的事情,但它只是行不通。看来我无法访问“执行”函数的模板重载(在“main”中调用)。

具体来说:为什么不能调用Execute的重载模板函数?

这是完整的程序:

#include "stdafx.h"
#include <functional>

class TransparentFunctionWrapper
{
public:
    virtual void Execute(std::function<void()> executeFunction) = 0;

    template<class C>
    C Execute(std::function<C(void)> executeFunction) // template-overload of the abstract function which will implicitly call it
    {
        C ret;
        Execute( // calls the abstract function with a lambda function as parameter
        [ret, executeFunction](void) -> C       // lambda declaraction
        {                                       //
            ret = executeFunction;              // lambda body
        });                                     // 
        return ret;
    }
};

class ExampleExecutor : public TransparentFunctionWrapper
{
public:
    virtual void Execute(std::function<void()> executeFunction)
    {
        printf("executed before.");
        executeFunction();
        printf("executed after.");
    }
};

void DoStuff() {}
int ReturnStuff() { return -5; }

int main()
{
    ExampleExecutor executor;

    executor.Execute(DoStuff);
    int i = executor.Execute<int>(ReturnStuff);     // Why does this not work? ERROR: "type name is not allowed"

    getchar();
    return 0;
}

注意:Visual Studio 标记

Execute<int>(ReturnStuff) // "int" is marked as Error: type name is not allowed

编译出错误

"type 'int' unexpected"

感谢所有愿意提供帮助的人!

【问题讨论】:

  • 警告:ret 是按值捕获到您的 lambda 中的。这不会编译,因为您试图在 lambda 不可变的情况下将其分配到正文中,并且无论如何都不会做您想做的事情。使用[&amp;]引用捕获。
  • 感谢您指出这一点,我实际上正在调试这个。 :)

标签: c++ function templates call overloading


【解决方案1】:

ExampleExecutor::Execute 没有覆盖TransparentFunctionWrapper::Execute,而是将其隐藏在executor.Execute&lt;int&gt; 调用中。

您必须显式调用TransparentFunctionWrapper::Execute,因为它被ExampleExecutor::Execute 隐藏。这是一种可能的方法:

int i = executor.TransparentFunctionWrapper::Execute<int>(ReturnStuff); 

live example on coliru

【讨论】:

  • 非常感谢!你知道通过“ExampleExecutor”类公开“Execute”的方法吗?用“executor.TransparentFunctionWrapper::Execute”调用它相当不方便。 :P
  • @Oachkatzl:您可以在调用TransparentFunctionWrapper::ExecuteExampleExecutor 中提供一个具有不同名称的包装器 (例如ExecuteBase
  • 感谢您的回答!奇怪的是,如果我将“Execute(function)”重命名为“ExecuteWithReturn”,“ExampleExecutor”不会隐藏它。这并不能真正让我满意,因为我想重载它以明确他们基本上在做同样的事情,但我想这和它会得到的一样好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多