C++ undefined ссылка на пространство имен Visual Studio Code

У меня неопределенная справочная проблема со следующими сценариями C++:

Main.cpp

#include"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_A.hpp"
#include"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_B.hpp"
#include"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_C.hpp"

#include <iostream>
#include <limits.h>
#include <sstream> 
#include <stdbool.h>

using namespace ns_young_tableau_A;
using namespace ns_young_tableau_B;
using namespace ns_young_tableau_C;

///MAIN
int main() {

ns_young_tableau_C::YoungTableau_C YOUNG_TABLEAU;

///Tableau size
ns_young_tableau_A::YoungTableau_A::Tableau_T Tableau;
Tableau.m = 4;
Tableau.n = 4;
Tableau.elements = NULL;


//'Prova'
//'---------------------------------------------------------------------------------------------------------'

ns_young_tableau_B::YoungTableau_B MCYT;
ns_young_tableau_A::YoungTableau_A::Cell_T CurrentYT; 

CurrentYT = MCYT.MakeCellYT(Tableau.m, Tableau.n);
//'------------------------------------------------------------------------- --------------------------------'

///Initialize elements in the tableau
int elements[Tableau.m * Tableau.n];

/// # of elements in the tableau
int ElementSize = sizeof(elements)/sizeof(*elements);

///Initialize tableau
Tableau = {Tableau.m, Tableau.n,elements};
cout << "Tableau!\n" << endl;


YOUNG_TABLEAU.InitEmptyTableauYT(Tableau);


///Insert elements in the tableau
YOUNG_TABLEAU.InsertYT(Tableau,9);
YOUNG_TABLEAU.InsertYT(Tableau,16);
YOUNG_TABLEAU.InsertYT(Tableau,3);
YOUNG_TABLEAU.InsertYT(Tableau,2);
YOUNG_TABLEAU.InsertYT(Tableau,4);
YOUNG_TABLEAU.InsertYT(Tableau,8);
YOUNG_TABLEAU.InsertYT(Tableau,5);
YOUNG_TABLEAU.InsertYT(Tableau,14);
YOUNG_TABLEAU.InsertYT(Tableau,12);

cout << "\nAfter insert:" << endl;

///Inserted elements
YOUNG_TABLEAU.TableauPrint(Tableau);

///Minimum element extracted from the tableau
cout << "\n Minimum element in the tableau: " <<YOUNG_TABLEAU.ExtractMinYT(Tableau) << endl;

///Square of a number calculating using a constexpr
int Value = YOUNG_TABLEAU.SquareConstExpr(Tableau.n);
///Square of a number calculating using template function
int Value2 = YOUNG_TABLEAU.SquareTemplate(Tableau.n);

//========== ?? Revise resulting indexes ?? ==========
///Find a specific element in a tableau
if (YOUNG_TABLEAU.FindYT(Tableau, Value))
    cout << "Value founded icn position (" << ns_young_tableau_i_C::c.i << 
"," << ns_young_tableau_i_C::c.j << ")" << endl;

int ArrayElements[16] = {9,16,3,2,4,8,5,14,12,1,17,13,6,9,15,26};

///Sorted elements in the tableau
YOUNG_TABLEAU.SortYT(ArrayElements,Tableau.m);

cout << "\nSorted Elements:\n" << endl;

///Print sorted elements in the tableau
for(int i = 0; i < Tableau.m * Tableau.m; i++){
    cout << " " <<  ns_young_tableau_i_C::Array2[i];
}

cout << "\n" << endl;

return 0;
}

header_A.hpp

//Avoid multiple inclusions of a header file in a translation
//unit
#pragma once

#include <stddef.h>
//#include <iostream>
#include <ostream>
#include <istream>

#include <limits.h>
#include <sstream>
#include <stdbool.h>


/** @brief "Namespace YoungTableau"
* Contains functions and structures to make and manage a tableau
*/
namespace ns_young_tableau_A {


/**
 * @brief "YoungTableau_A"
 * @tparam T
 */
class YoungTableau_A {
public:

/**
     * @brief "Cell (i,j)"
     * @details  "Single cell in the tableau"
     *            i,j: cell indexes
     */
    struct Cell_T {
    //typedef struct Cell_T {

        int i;
        int j;

    } cell_YT,c,d,l,r,u,CurrentYT;

    /**
     * @brief "Tableau"
     * @details  "Young Tableau (table)",
     *      elements: elements in the tableau
     *      m: # of rows
     *      n: # of columns
     */
     struct Tableau_T{
    //typedef struct Tableau_T{

        int m;
        int n;
        int *elements;

    } Tableau,TableauSorted;



///Accepted movements 
///---------------------------------------------------------
/**
* @brief "Upward: Up"
* @details "Upward movement from the current cell"
     * @tparam  R
     * @param[in] c
     * @return position (i,j)
     */
    template<typename T>
    T UpYT(T c);

    /**
     * @brief   Downward: Down
     * @details "Downward movement from the current cell"
     * @tparam  R
     * @param[in] c
     * @return position (i,j)
     */
    template<typename T>
    T DownYT(T c);

    /**
     * @brief   Leftward: Left
     * @details "Leftward movement from the current cell"
     * @tparam  R
     * @param[in] c
     * @return position (i,j)
     */
    template<typename T>
    T LeftYT(T c);

    /**
     * @brief   Rightward: Right
     * @details "Rightward movement from the current cell"
     * @tparam  R
     * @param[in] c
     * @return position (i,j)
     */
    template<typename T>
    T RightYT(T c);

///---------------------------------------------------------
};

} // namespace young_tableau


//namespace YT = young_tableau;

#include "impl/header_A.i.hpp"

header_A.i.hpp

namespace ns_young_tableau_i_A {

template<typename T>
T UpYT(T c){

    T Result = {c.i - 1, c.j};

    return Result;
}

template<typename T>
T DownYT(T c){

    T Result = {c.i + 1, c.j};

    return Result;
}

template<typename T>
T LeftYT(T c){

   T Result = {c.i, c.j - 1};

    return Result;
}

template<typename T>
T RightYT(T c){

    T Result = {c.i, c.j + 1};

    return Result;
}


} // namespace young_tableau

header_B.hpp

//Avoid multiple inclusions of a header file in a translation
//unit
#pragma once

#include "C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_A.hpp"
#include <cstddef>
#include <stdbool.h>
#include <limits.h>
#include <iostream>
#include <sstream> 

//using namespace ns_young_tableau_A;

/** @brief Namespace brief
* Contains functions and structures to make and manage a tableau
*/
namespace ns_young_tableau_B{

/**
 * @brief "YoungTableau_B"
 * @details "Inhereted from A class"
 * @tparam T
 */

class YoungTableau_B {
public:

/// @brief Create an object with methods in YoungTableau_A class
//YoungTableau_A YOUNG_TABLEAU_A;

/**
* @brief "Make cell"
* @details Return the value in position (i,j) from the Young     Tableau 
* @tparam  R
* @param[in] i
* @param[in] j
* @return position (i,j)
*/
 template<typename T>
        ns_young_tableau_A::YoungTableau_A::Cell_T MakeCellYT(T i, T j);


        /**
         * @brief "Within Cell"
         * @details Check that current position is within the Young Tableau contour 
         * @tparam  R
         * @param[in] tableau
         * @param[in] c
         * @return 'yes' if the element c exists in the tableau
         *         'no' otherwise
         */
        template<typename R,typename T>
        bool WithinYT(R *Tableau, T c);

        /**
         * @brief "Get cell"
         * @details Find and return the value of the element 
         * in 'index' position (calculated from i,j indexes)
         * @tparam  R
         * @param[in] tableau
         * @param[in] c
         * @return corrispondent element in the tableau
         */
        template<typename R,typename T>
        int GetYT(R *Tableau, T c);

        /**
         * @brief "Set cell"
         * @details Set a value for the element in 'index' position  
         * @tparam  R
         * @param[in] tableau
         * @param[in] c
         * @param[in] value
         * @return void
         */
        template<typename R,typename T>
        void SetYT(R *Tableau, T c, int Value);
};


} // namespace young_tableau

//namespace YT = young_tableau;


#include "impl/header_B.i.hpp"

header_B_i.hpp

//using namespace ns_young_tableau_A;

namespace ns_young_tableau_i_B {

template<typename T>
ns_young_tableau_A::YoungTableau_A::Cell_T MakeCellYT(T i, T j){

    T Result = {i,j};

    return Result;
}       


template<typename R,typename T>
bool WithinYT(R Tableau, T c){
    return (c.i >= 0 && c.j >= 0 && c.i < Tableau->m && c.j < Tableau->n);
}


template <typename R, typename T>
int GetYT(R Tableau, T c){

    auto IndexYT = c.i * Tableau->n + c.j;

    return Tableau->elements[IndexYT];
}


///Set a value for the element in 'index' position  
template<typename R, typename T>
void SetYT(R Tableau, T c, int Value){

    auto IndexYT = c.i * Tableau->n + c.j;

    Tableau->elements[IndexYT] = Value;
}
// namespace young_tableau

header_C.hpp

//Avoid multiple inclusions of a header file in a translation
//unit
#pragma once
#include"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_A.hpp"
#include"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_C.hpp"

#include <cstddef>
#include <stdbool.h>
#include <limits.h>
#include <iostream>
#include <sstream> 

//using namespace ns_young_tableau_A;
//using namespace ns_young_tableau_B;

/// @brief Namespace brief
/// Contains functions and structures to make and manage a tableau 
namespace ns_young_tableau_C {

/**
 * @brief "YoungTableau_C"
 * @details "Inhereted from A and B classes"
 * @tparam T
 */

class YoungTableau_C {
public:

    /**
     * @brief "Tableau print"
     * @details Print tableau on screen
     * @tparam  R
     * @param[in] tableau
     * @return void
     */
    template<typename R>
    void TableauPrint(R Tableau);

    /**
     * @brief "Init empty tableau"
     * @details Create a new empty tableau
     * @tparam  R
     * @param[in] tableau
     * @return correspondent element in the tableau
     */
    template<typename R>
    void InitEmptyTableauYT(R Tableau);

    /**
     * @brief "Extract tableau min value"
     * @details Extract the element with minimum value from the Young Tableau 
     * @tparam  R
     * @param[in] tableau
     * @return minimum value in the tableau
     */
    template<typename R>
    int ExtractMinYT(R Tableau);


    /**
     * @brief "Insert new element in the tableau"
     * @details Insert a new element in the Young Table 
     * @tparam  R
     * @param[in] tableau
     * @param[in] key
     * @return void
     */
    template<typename R>
    R InsertYT(R Tableau, int Key);


    /**
     * @brief "Sort elements of the tableau"
     * @details Sort elements in the Young Tableau
     * @tparam  R
     * @param[in] tableau elements
     * @param[in] size_sqrt
     * @return void
     */ 
    template<typename R, typename T>
    void SortYT(R Array, T SizeSqrt);


    /**
     * @brief "Find inside tableau"
     * @details Find an existing element in the Young Tableau 
     * @tparam  R
     * @param[in] tableau 
     * @param[in] key
     * @return 'yes' if element found
     *         'no' otherwise
     */ 
    template<typename R>
    int FindYT(R Tableau, int Key);

    /**
     * @brief Square (constant expression)
     * @details Constant expression (computed at compile-time)
     * @tparam R
     * @param[in] value
     * @return square of value
     */
    template<typename R>
    constexpr SquareConstExpr(R Value) {
        return Value * Value;
    }

        /**
     * @brief Square  (template function)
     * @details template function (computed at compile-time)
     * @tparam R
     * @param[in] value
     * @return square of value
     */
    template<typename R>
    R SquareTemplate(R a) {
        return a * a; 
    }
};

} 

//namespace YT = young_tableau;


#include "impl/header_C.i.hpp"

Похоже, что компилятор не может найти правильные ссылки на файлы hpp. На самом деле я использую редактор кода Visual Studio. Я добавил путь к файлам .hpp (header_A, header_B, header_C) в c_cpp_properties.json следующим образом ...


"intelliSenseMode": "msvc-x64",
        "browse": {
            "path": [
                "${workspaceFolder}",
                "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_A.hpp","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_B.hpp","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_C.hpp","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/header_Source.hpp",
                "C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/tr1",
                "C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++",
                "C:/MinGW/lib/gcc/mingw32/6.3.0/include",
                "C:/MinGW/lib/gcc/mingw32/6.3.0/include/c++/mingw32",

"C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Source.cpp*",
                "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/atlmfc/include/*",
                "C:/Program Files (x86)/Windows Kits/8.1/Include/um",
                "C:/Program Files (x86)/Windows Kits/8.1/Include/shared",
                "C:/Program Files (x86)/Windows Kits/8.1/Include/winrt"
            ],
            "limitSymbolsToIncludedHeaders": true,
            "databaseFilename": ""

.... и попытался скомпилировать с помощью следующей команды g ++ в файле tasks.json:

Tasks.json

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
    {
        "label": "echo",
        "type": "shell",
        "command": "g++",
        "args": ["-g","-Iinclude","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp","C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/include/*.hpp","-o","Main"],
        "group": {
            "kind": "build",
            "isDefault": true
        }
    }
]
}

Это одна из возможных ошибок, которая появляется:


C:\Users\Steve\AppData\Local\Temp\ccIsSjRK.o: In function `main':
C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp:68:     undefined reference to `ns_young_tableau_A::YoungTableau_A::Cell_T     ns_young_tableau_B::YoungTableau_B::MakeCellYT<int>(int, int)'
C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp:82:     undefined reference to `void     ns_young_tableau_C::YoungTableau_C::InitEmptyTableauYT<ns_young_tableau_A::Young    Tableau_A::Tableau_T>(ns_young_tableau_A::YoungTableau_A::Tableau_T)'
C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp:86:     undefined reference to `ns_young_tableau_A::YoungTableau_A::Tableau_T     ns_young_tableau_C::YoungTableau_C::InsertYT<ns_young_tableau_A::YoungTableau_A:    :Tableau_T>(ns_young_tableau_A::YoungTableau_A::Tableau_T, int)'
C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp:87:     undefined reference to `ns_young_tableau_A::YoungTableau_A::Tableau_T     ns_young_tableau_C::YoungTableau_C::InsertYT<ns_young_tableau_A::YoungTableau_A:    :Tableau_T>(ns_young_tableau_A::YoungTableau_A::Tableau_T, int)'
C:/Users/Steve/Desktop/Project/MyProject_YoungTableau/src/Main.cpp:88:     undefined reference to `ns_young_tableau_A::YoungTableau_A::Tableau_T     ns_young_tableau_C::YoungTableau_C::InsertYT<ns_young_tableau_A::YoungTableau_A:    :Tableau_T>(ns_young_tableau_A::YoungTableau_A::Tableau_T, int)'

Я не могу понять, в чем проблема. Какое-то время бился головой об эту проблему. Надеюсь, я был достаточно ясен :)

Спасибо всем за помощь :)


ExtractMinYT

template<typename R>
    int YoungTableau_C::ExtractMinYT(R Tableau){

  //          CurYT = {0,0};
            //Next = {0,0};

            ns_young_tableau_A::YoungTableau_A::Cell_T CurYT2;
            //CurYT2 = MCYT.MakeCellYT(Tableau.m, Tableau.n);
            CurYT2 = {0,0};
            ns_young_tableau_A::YoungTableau_A::Cell_T Next2;
            //Next2 = MCYT.MakeCellYT(Tableau.m, Tableau.n);
            Next2 = {0,0}; 

            ///Minimum element found in the tableau
            int MinYT = 0; 

            ///The new minimum element found
            int NewOne = INT_MAX;

            /**Start with the current minimum fixed to an Infinitive value
               Polymorphism: 'get' from YoungTableau_C Class */
            MinYT = GYT.GetYT(Tableau,CurYT2);

            ///Polymorphism: 'set' inhereted from YoungTableau_B class
            SYT.SetYT(Tableau,CurYT2, INT_MAX);

            /**Find the minimum element in the tableau comparing the current element
               current_YT with the neighbours and exchange it with the smallest */
            while (true) {

                ///Minimum element actually found
                int SmallestYT;

                ///Move downward from the current position
                d = DYT.DownYT(CurYT2);

                ///Move rightward from the current position
                r = RYT.RightYT(CurYT2);


                /** If there is a smaller element moving downward from the current position,
                move downward the cursor and update the smallest with the new element found */
                if (WYT.WithinYT(Tableau,d) && GYT.GetYT(Tableau,d) < NewOne) {
                    Next2 = d;
                    SmallestYT = GYT.GetYT(Tableau,Next2);
                } else {
                    SmallestYT = NewOne;
                }


                /** If there is a smaller element moving rightward from the current position,
                   move rightward the cursor and update the smallest with the new element found */
                if (WYT.WithinYT(Tableau,r) && GYT.GetYT(Tableau,r) < SmallestYT) {
                    Next2 = r;
                    SmallestYT = GYT.GetYT(Tableau, Next2);
                }

                /** If the last element found is the smallest in the tableau,
                update the current position of the tableau with this element and return it */
                if (NewOne == SmallestYT){     
                    SYT.SetYT(Tableau,CurYT2,NewOne);
                    break;
                }

                SYT.SetYT(Tableau,CurYT2, SmallestYT);
                CurYT2 = Next2;
            }

            return MinYT;
        }

Было бы полезно, если бы вы также предоставили header_C.hpp.

ChrisD 07.11.2018 21:07

Заранее большое спасибо за участие, ChrisD :) Я добавил header_C.hpp. Я не загрузил header_C_i.hpp, потому что он слишком длинный и очень похож на header_B_i.hpp (если я решу проблему для header_B_i.hpp, я также решу ее для header_C.hpp и для header_C_i.hpp :))

SteveFierro250690 07.11.2018 22:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
1 116
1

Ответы 1

Для первой ошибки есть пара проблем. Ваш класс YoungTableau_B определен в пространстве имен ns_young_tableau_B, однако реализация MakeCellYT определена в пространстве имен ns_young_tableau_i_B. Они должны находиться в одном пространстве имен. Во-вторых, поскольку MakeCellYT является функцией-членом, ее реализация должна быть определена как

template<typename T>
ns_young_tableau_A::YoungTableau_A::Cell_T YoungTableau_B::MakeCellYT(T i, T j)

(обратите внимание на добавление YoungTableau_B::)

Как только это будет исправлено, вы столкнетесь с проблемой, когда вы вызывали эту функцию с параметром шаблона int, поэтому строка

T Result = {i,j};

пытается присвоить список инициализаторов целому числу, что является ошибкой. Возможно вы имели в виду Cell_T Result = {i,j};

В общем, я не уверен, что вам действительно нужно разбивать реализацию на отдельные файлы, такого рода ошибки было бы легче диагностировать, если бы вы просто определили и реализовали класс в одном заголовке.

Большое спасибо за ответ @ChrisD. На самом деле мне не нужно разбивать реализацию на отдельные заголовки. Я сделал это в качестве упражнения, чтобы изучить, как ссылки связаны в разных заголовках :). Я постараюсь сделать, как ты сказал. Можно ли было бы отредактировать код, чтобы сохранить разные пространства имен, как я?

SteveFierro250690 08.11.2018 08:56

Вам необходимо определить функцию в том же пространстве имен, в котором вы ее объявили. Если вы хотите сохранить определение MakeCellYT в пространстве имен, в котором он сейчас находится, вы можете записать его как ::ns_young_tableau_B::YoungTableau_B::MakeCellYT.

ChrisD 08.11.2018 19:36

Я изменил файлы header_i_.hpp, используя то же пространство имен. Работает :) Большое спасибо :)

SteveFierro250690 08.11.2018 21:02

Идеально @ChrisD. Большое тебе спасибо :)

SteveFierro250690 10.11.2018 17:40

Мне нужна ваша помощь по другой проблеме, которую я обнаружил в коде. Функция YOUNG_TABLEAU.ExtractMinYT (Tableau) правильно вызывается из Main.cpp. Я определил и инициализировал пару переменных Cell_T в верхней части функции CurYT2 и Next2. Во время отладки я обнаружил, что эти переменные не создаются: отладчик переходит прямо к «int MinYT = 0;» из "ns_young_tableau_A :: YoungTableau_A :: Cell_T CurYT2;". Обе переменные не появляются среди локальных переменных, и я не знаю, в чем ошибка. Заранее благодарим вас за любые предложения :)

SteveFierro250690 10.11.2018 18:18

Не видя кода, я могу только предполагать, но две вещи, которые могут вызвать это: либо источник не синхронизирован с отлаживаемым двоичным файлом, либо, в качестве альтернативы, вы больше ничего не делаете с этими переменными, поэтому компилятор только что оптимизировал их.

ChrisD 12.11.2018 19:19

Как может случиться так, что источник не синхронизирован? Это странно. Я их инициализировал, и они должны появиться среди местных. Я бы передал вам скриншот казни, но у меня пока недостаточно прав :(

SteveFierro250690 14.11.2018 00:51

Другие вопросы по теме