C++ 从未命名命名空间调用函数时出错

C++ Error calling a function from unnamed namespace

提问人:unit5016 提问时间:9/12/2023 最后编辑:Jan Schultkeunit5016 更新时间:9/12/2023 访问量:108

问:

我正在尝试完成初学者 comp sci 的作业。我们只是在学习空间分配和使用标头,以及动态内存分配。其中一个要求是,我们必须在 const 变量和函数声明的标头中使用未命名的命名空间。我在第 28 行收到一个关于“未定义对匿名命名空间的引用”的编译错误,我不确定如何解决这个问题或是什么语法或拼写错误导致了它。我们只是在学习这个,所以不要太苛刻地判断哈哈。

我的图书馆.hpp
#include <iostream>
#include <memory>

#ifndef MYLIBRARY_HPP
#define MYLIBRARY_HPP

namespace
{
    int counter = 0;
    const int SIZE = 10;
    std::unique_ptr<char[]> deleteRepeats(char arr[]);
}

#endif // MYLIBRARY_HPP
主 .cpp
using std::cin;
using std::cout; //using declarations to avoid namespace std
using std::endl;

int main()
{
   
    char originalArray[SIZE]; //declaration of array that will be used in the program and all its values
    originalArray [0] = 'a';
    originalArray [1] = 'b';
    originalArray [2] = 'b';
    originalArray [3] = 'c';
    originalArray [4] = 'a';
    originalArray [5] = 'c';
    originalArray [6] = 'a';
    originalArray [7] = 'c';
    originalArray [8] = 'b';
    originalArray [9] = 'c';
    std::unique_ptr<char[]> noRepeats = deleteRepeats(originalArray); //function call

    cout << "the amount of repeats is... " << SIZE-counter << endl; //prints out the number of repeats

    for(int i =0; i<counter; i++) //displays new array
    {
        cout << noRepeats[i] << endl;
    }

    return 0;
}
函数:.cpp
#include <iostream>
#include <memory>

//my function definitions
namespace
{
    //Precondition: an array of defined size contains only valid characters
    //Postconition: a new array is generated with only unique values
    std::unique_ptr<char[]> deleteRepeats(char arr[]) //goes through the array and checks if it has repeats
    {
        for(int i=0; i<SIZE/2; i++)
        {
            if(arr[i] = arr[SIZE -1-i]) //marks any repeats
            {
                arr[i] = '-';
                arr[SIZE-1-i] = '-';
            }
        }
        for(int i =0; i<SIZE; i++) //counts new array
        {
            if(arr[i] != '-')
            {
                counter++;
            }
        }
        std::unique_ptr<char[]> newArray(new char[counter]); //declares a new array using a pointer
        int location = 0;
        for(int i = 0; i<SIZE; i++)
        {
            if(arr[i] != '-')
            {
                newArray[location++] = arr[i];
            }
        }
        return newArray;
    }
}
C++ 命名空间 头文件

评论

1赞 PaulMcKenzie 9/12/2023
获取代码并将其全部设置为一个文件不会显示任何错误,但您需要修复它的警告。
1赞 PaulMcKenzie 9/12/2023
仅供参考 - 有比您的尝试更简单的方法。 然后,或者干脆将所有内容存储到 中,然后从内容创建一个新数组。//Postconition: a new array is generated with only unique valuesstd::sortstd::uniquestd::setstd::set
0赞 unit5016 9/12/2023
@PaulMcKenzie 真的吗?每次我在类给我们的软件中编译时,我都会在 main 中的函数调用中收到一个危险信号.cpp“C:\Users\Shaun\Desktop\CS Work\CS2 Assign 1-A\main.cpp|28|undefined reference to '(anonymous namespace)::d eleteRepeats(char*)'| ”
0赞 PaulMcKenzie 9/12/2023
在链接中获取代码,将其完全复制并粘贴到一个文件中。编译它。你仍然看到错误吗?
0赞 Jan Schultke 9/12/2023
头文件不应包含未命名命名空间中的声明。

答:

0赞 BoP 9/12/2023 #1

每次包含标头时,都会获得一个具有不同机密名称的新未命名命名空间。

使它“工作”的唯一方法是只包含一次,并且只使用该源文件中的对象。有点打败了拥有该头文件的原因。

无法引用其他源文件中的未命名命名空间。这就是构造的目的!

评论

0赞 Jan Schultke 9/12/2023
好吧,还有......那么我们该如何解决OP的问题呢?
0赞 BoP 9/12/2023
我们真的没有。一个符合法律条文的解决方案是在命名空间之外拥有另一个函数,然后在一个源中让该函数调用匿名函数。但是,为什么要费心将该命名空间放在标头中呢?
1赞 tbxfreeware 9/12/2023 #2
两个版本的功能deleteRepeats

您的程序有两个翻译单元:和 。每个都有自己的匿名命名空间。在 的匿名命名空间中声明和/或定义的名称只能在 中引用(即使用)。同样,在 的匿名命名空间中声明和/或定义的名称只能在 中引用。main.cppMyFunction.cppmain.cppmain.cppMyFunction.cppMyFunction.cpp

这意味着 中定义的函数不能从 调用。相反,声明自己的函数(在其匿名命名空间中),该函数与 中定义的函数完全不同。在 中,函数是 delcareed,但从不接收定义。deleteRepeatsMyFunction.cppmain.cppmain.cppdeleteRepeatsMyFunction.cppmain.cppdeleteRepeats

错误消息:

“对匿名命名空间的未定义引用”

指 中的函数,它没有定义。deleteRepeatsmain.cpp

我建议你与你的老师核实一下,看看哪些名字应该在匿名命名空间中。

附带问题

正如评论中所指出的,中给出的定义存在几个问题。deleteRepeatsMyFunction.cpp

  1. 比较应使用两个等号 (==),而不是赋值 (=) 使用的两个等号。
  2. 识别重复项的逻辑过于复杂/错误。

消除重复项的一种简单方法是创建一个 ,并在数组中插入所有元素。然后,您可以通过遍历集合的元素来创建一个新数组。std::set