C ++ неопределенная ссылка на пространство имен кода Visual Studio - PullRequest
0 голосов
/ 07 ноября 2018

У меня неопределенная проблема со ссылками на следующие скрипты 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;
        }

1 Ответ

0 голосов
/ 08 ноября 2018

Для первой ошибки есть пара проблем. Ваш класс 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};

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

...