【问题标题】:Allowing certain function call only if it is followed by another function仅当某个函数后面跟着另一个函数时才允许调用它
【发布时间】:2016-03-04 16:42:54
【问题描述】:

我想创建一个必须用 { } 大括号调用的函数。相似的 到 if、while 和 for 语句。这样做的原因是为了防止操作员在未添加必要代码的情况下调用该函数。

#include <iostream>

/* function to run the test */
bool runTest()
{
    std::cout "PASS" << std::endl;
    return true;
}

/* function will print the passed chars */
void newTest(const char *functionName, const char *testName)
{
    std::cout << functionName << " " << testName;
}

int main(void)
{
    /* OPTION 1 */
    /* You can call it like this */
    newTest("runTest", "TestName");
        runTest();
    / * OR */
    newTest("runTest", "TestName");
    {
        runTest();
    }

    /* OPTION 2 */
    /* I want the operator to be required to do */
    newTest("runTest", "TestName")
    {
        runTest();
    }
    return 0;
}

我希望选项 2 是正确的用法。因为使用选项 1,您可以这样称呼:

newTest("runTest", "TestName");
newTest("otherTest", "TestName");
   runTest();

但您不会对与第一次调用输出相关的 runTest() 进行必要的调用。

输出将是:

runTests TestName /*(NULL)*/
otherTest TestName PASS

这种调用方式只是检查以确保操作员在 newTest() 函数之后调用了测试。

理想情况下,如果操作员是完美的,他可以正确调用函数。

newTest("runTest", "TestName");
    runTest();
newTest("otherTest", "TestName");
   runTest();

但我想消除错误,但自动要求操作员在调用后使用 {} 调用该函数。

【问题讨论】:

  • 如果你想让一个函数运行用户提供的代码,你应该让你的函数接受一个函数/仿函数/lambda并在你的函数中运行它。
  • 这是个好主意,我不敢相信我没有想到那个大声笑。理想情况下,这样的事情会起作用newTest(runtests, "runTests", "TestName")

标签: c++ function macros brackets statements


【解决方案1】:

首先,那些“大括号”被称为“大括号”——您可能需要编辑您的问题,以便人们更好地理解。

除非有人在不告诉我的情况下更改了它; C++ 不能以这种方式工作。 此上下文中的大括号是为the scope of keywords, function-definitions, and initializer lists 明确保留的。

void Badger()
{ //this is fine, it's a function-definition
}
int main()
{
for(I =0; I < 5; I++)
   { //this is fine, for is a keyword.
   }
foo()
   { //This is not legal, foo must take it's perimeters within brackets, not braces.
   } 
}

如果您希望用户将代码传递给函数,您必须使用 Function-pointer 这样做,然后用户可以传递现有函数 or a lambda.

void Foo(bool (Function_ptr*) ()) { };
bool Function_To_Pass() { } ;
int main()
{
    Foo(&Function_To_Pass);
    Foo([]()
    {
        //Code to run here
    });
}

【讨论】:

  • 我不建议只使用函数指针。我会使其通用并采用任何可调用类型。另请注意,无法将捕获的 lambda 转换为函数指针。
  • C++11 引入了列表初始化,例如std::vector&lt;int&gt; vec { 1, 2, 3, 4, 5 };,但我看到你已经编辑了你的帖子以反映这一点。
  • 我尝试使用大括号的唯一原因是因为我看到它在其他代码中的用法并试图复制类似的结果。我相信它在其他代码中使用宏的方式。我喜欢你给出的两个选项。就像 Nathan 的评论一样,我认为这是最好的方法。
  • @TylerGajewski 我很高兴能帮上忙 - 就我个人而言,我不喜欢任何通用的东西,我更喜欢在所有情况下都非常严格的打字,但也许我是一个受虐狂。
【解决方案2】:
   #include <iostream>

/* function to run the test */
bool runTest()
{
    std::cout << " PASS" << std::endl;
    return true;
}

/* function will print the passed chars */
void newTest(bool (*function)(), const char *functionName, const char *testName)
{
    std::cout << functionName << " " << testName;
    function();
}

int main(void)
{
    newTest(runTest, "runTest", "TestName");

    return 0;
}

这将根据@JohnBargman 和@NathanOliver 的建议返回所需的结果。

理想情况下,runTest() 将允许操作员传入参数,runTest 函数将处理这些参数。所以我希望函数调用用大括号创建范围。喜欢:

newTest("runTests", "TestName")
{
    int number = 1;
    runTests(number);
}

但我想如果操作员使用此代码,他/她应该知道他/她可以使用大括号来创建范围。因此不需要。

【讨论】:

    猜你喜欢
    • 2017-08-23
    • 2016-04-11
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 2017-04-07
    • 2011-11-29
    相关资源
    最近更新 更多