【问题标题】:Functions not recognized as being part of namespace未被识别为命名空间一部分的函数
【发布时间】:2015-12-20 01:27:57
【问题描述】:

我正在编写一个类似于单元测试的简短程序,作为一个更大项目的一部分。我在“Utilities.hpp”文件中编写了一些简单的函数,我正在为其编写测试。这是代码...为了篇幅,一些函数定义被排除在外。

//Main.cpp
#ifdef RUN_TESTS

#include "Logger.hpp"
#include "UnitTester.hpp"


#define TEST_ALL

int main(int, char*[])
{
    logger::init();
    logger::setSeverityLevel(INFO);
    auto slg = logger::getSLogger();

    BOOST_LOG_SEV(slg, INFO) << "Starting Unit Tests...";

    testing::UnitTester testObject;
    testObject.runTests();
}

#endif

实用程序.hpp

#pragma once

#include <string>
#include <stack>
#include <vector>


namespace util
{
    void swapChars(char& a, char& b);   //flips two chars

    std::string reverseString(const std::string& str);  //stack based implementation of string inversion

    std::vector<std::string> splitStrAtSubstr(const std::string& str, const std::string& split);    //splits string into parts seperated by "split"
}

实用程序.cpp

#include "Utilities.hpp"



void util::swapChars(char& a, char& b)
{

...

}

std::string util::reverseString(const std::string& str)
{
...
}


std::vector<std::string> util::splitStrAtSubstr(const std::string& str, const std::string& split)
{
...
}

最后是 UnitTester 类... UnitTester.hpp

#pragma once
#define RUN_TESTS
#define RUN_ALL
#ifdef RUN_TESTS

#include "Logger.hpp"
#include <string>
#include <vector>

namespace testing
{

    class UnitTester
    {
    public:
        UnitTester();
        ~UnitTester();
        void runTests();

    private:
        src::severity_logger<severity_level> testLogger;

        void utilities();
        void logging();
        void resourceGroup();
        void resourceManager();
        void INIParser();
    };

}
#endif

UnitTester.cpp

#include "UnitTester.hpp"
#ifdef RUN_TESTS


void testing::UnitTester::runTests()
{
#ifdef RUN_ALL
    utilities();
    logging();
    resourceGroup();
    resourceManager();
    INIParser();
#elif
    #ifdef TEST_UTILITIES
        utilities();
    #endif
    #ifdef TEST_LOGGING
            logging();
    #endif
    #ifdef TEST_RESOURCE_GROUP
            resourceGroup();
    #endif
    #ifdef TEST_RESOURCE_MANAGER
            resourceMananager();
    #endif
    #ifdef TEST_INI_PARSER
            INIParser();
    #endif
#endif
}

//PRIVATE FUNCTIONS

void testing::UnitTester::utilities()
{
#include "Utilities.hpp"

    BOOST_LOG_SEV(testLogger, INFO) << "Now testing: void util::swapChars(char& a, char& b);";
    char a = 'a', b = 'b';
    util::swapChars(a, b);
    if (a != 'b' || b != 'a') { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::swapChars failed."; }

    BOOST_LOG_SEV(testLogger, INFO) << "Now testing: std::string util::reverseString(const std::string& str);";
    if (util::reverseString("myString") != "gnirtSym") { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::reverseString failed.  IN: \"myString\""; }
    if (util::reverseString("MYSTRING ") != " GNIRTSYM") { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::reverseString failed.  IN: \"MYSTRING \""; }
    if (util::reverseString("aaaaaa") != "aaaaaa") { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::reverseString failed.  IN: \"aaaaaa\""; }
    if (util::reverseString("This Is An Extended TEST") != "TSET dednetxE nA sI sihT") { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::reverseString failed.  IN: \"This Is An Extended Test\""; }
    if (util::reverseString("\"\\\"Escape") != "epacsE\"\\\"") { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::reverseString failed.  IN: \"\"\\\"Escape\""; }

    BOOST_LOG_SEV(testLogger, INFO) << "Now testing: std::vector<std::string> splitStrAtSubstr(const std::string& str, const std::string& split)";
    std::vector<std::string> expected("One", "Two", "Three");
    std::vector<std::string> expected2("One", "Three");
    if (util::splitStrAtSubstr("One.Two.Three", ".") != expected) { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::splitStrAtSubstr failed. IN: \"One.Two.Three\", \".\""; }
    if (util::splitStrAtSubstr("One\"Two\"Three", "\"") != expected) { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::splitStrAtSubstr failed. IN: \"One\"Two\"Three\", \"\"\""; }
    if (util::splitStrAtSubstr("OneTwoThree", ".") != expected) { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::splitStrAtSubstr failed. IN: \"One.Two.Three\", \".\""; }
    if (util::splitStrAtSubstr("OneTwoThree", "Two") != expected) { BOOST_LOG_SEV(testLogger, ERROR) << "Input to util::splitStrAtSubstr failed. IN: \"OneTwoThree\", \"Two\""; }

}

void testing::UnitTester::logging()
{
#include "Logger.hpp"
}

void testing::UnitTester::resourceGroup()
{
#include "ResourceManager\ResourceGroup.hpp"
}

void testing::UnitTester::resourceManager()
{
#include "ResourceManager\ResourceGroup.hpp"
}

void testing::UnitTester::INIParser()
{
#include "INIParser.hpp"
}
#endif

我认为这是我遇到的不同错误的代表性示例。我会把我认为最可疑的放在最上面。正如他们经常做的那样,许多错误只是由其他错误引起的......

关于 Utilities.hpp 中的函数声明:

错误 14 错误 C2039:“向量”:不是“标准”的成员
错误 13 错误 C2143:语法错误:在 '&' 之前缺少 ','
错误 15 错误 C2143:语法错误:缺少 ';'在'之前 错误 10 错误 C2039: 'string' : is not a member of 'std'

在 UnitTester.hpp 中调用 BOOST_LOG_SEV:

错误 69 错误 C2597:非法引用非静态成员 'testing::UnitTester::testLogger'
错误 49 错误 C2228:'.stream' 左侧必须有类/结构/联合 错误 63 错误 C2228: '.open_record' 的左侧必须有类/结构/联合

关于 UnitTester.cpp 中的函数调用:

错误 51 错误 C2039: 'splitStrAtSubstr' : 不是 'util' 的成员

错误 31 错误 C2664: 'int util::reverseString(const int)' : 无法将参数 1 从 'const char [10]' 转换为 'const int' ^^ 发生是因为编译器找不到 std::string 作为类型并且默认为 int

这些似乎是最重要的错误。对我来说,这个问题几乎肯定会出现在 Utilities.hpp 中,编译器似乎无法识别 std::string 和 std::vector 并且对函数声明提出了一些奇怪的解释。

提前致谢。

【问题讨论】:

  • 你得到一个错误,说vector没有在你第一次做#include &lt;vector&gt;的头文件中定义?你确定吗?看起来有些东西你可能不会以某种方式向我们展示。一方面,除了Utilities.cpp 之外,您永远不会在任何地方#include &lt;Utilities.h&gt;,这是没有意义的。

标签: c++ unit-testing boost


【解决方案1】:

您包含来自函数体内部的文件,我不认为它应该像这样使用。

#include 是一个预编译器指令。预编译器甚至在实际编译器启动之前运行。这使它能够修改代码。就像#define 可以替换某些单词一样,#include 可以包含整个文件。

void testing::UnitTester::logging()
{
#include "Logger.hpp"
}

想象一下编译器实际上会收到什么,例如,如果您将 #include "Logger.hpp" 替换为 Logger.hpp 的内容。

请不要在函数体内使用#include

【讨论】:

  • 确实,C++ 标准明确指出,“翻译单元应仅包含任何外部声明或定义之外的标头”。虽然该标准专门讨论了标准定义的标头,但明智的做法是对任何标头执行相同的操作,除了一些专门设计用于在函数定义中使用的极少遇到的标头。
  • 解决了所有问题。我想我是想太花哨了。
猜你喜欢
  • 2018-04-08
  • 2016-04-03
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 2023-04-05
  • 2014-04-29
  • 2014-11-11
  • 2016-05-31
相关资源
最近更新 更多