У меня неопределенная справочная проблема со следующими сценариями C++:
#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;
}
//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"
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
//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"
//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
//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:
{
// 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)'
Я не могу понять, в чем проблема. Какое-то время бился головой об эту проблему. Надеюсь, я был достаточно ясен :)
Спасибо всем за помощь :)
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;
}
Заранее большое спасибо за участие, ChrisD :) Я добавил header_C.hpp. Я не загрузил header_C_i.hpp, потому что он слишком длинный и очень похож на header_B_i.hpp (если я решу проблему для header_B_i.hpp, я также решу ее для header_C.hpp и для header_C_i.hpp :))





Для первой ошибки есть пара проблем. Ваш класс 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. На самом деле мне не нужно разбивать реализацию на отдельные заголовки. Я сделал это в качестве упражнения, чтобы изучить, как ссылки связаны в разных заголовках :). Я постараюсь сделать, как ты сказал. Можно ли было бы отредактировать код, чтобы сохранить разные пространства имен, как я?
Вам необходимо определить функцию в том же пространстве имен, в котором вы ее объявили. Если вы хотите сохранить определение MakeCellYT в пространстве имен, в котором он сейчас находится, вы можете записать его как ::ns_young_tableau_B::YoungTableau_B::MakeCellYT.
Я изменил файлы header_i_.hpp, используя то же пространство имен. Работает :) Большое спасибо :)
Идеально @ChrisD. Большое тебе спасибо :)
Мне нужна ваша помощь по другой проблеме, которую я обнаружил в коде. Функция YOUNG_TABLEAU.ExtractMinYT (Tableau) правильно вызывается из Main.cpp. Я определил и инициализировал пару переменных Cell_T в верхней части функции CurYT2 и Next2. Во время отладки я обнаружил, что эти переменные не создаются: отладчик переходит прямо к «int MinYT = 0;» из "ns_young_tableau_A :: YoungTableau_A :: Cell_T CurYT2;". Обе переменные не появляются среди локальных переменных, и я не знаю, в чем ошибка. Заранее благодарим вас за любые предложения :)
Не видя кода, я могу только предполагать, но две вещи, которые могут вызвать это: либо источник не синхронизирован с отлаживаемым двоичным файлом, либо, в качестве альтернативы, вы больше ничего не делаете с этими переменными, поэтому компилятор только что оптимизировал их.
Как может случиться так, что источник не синхронизирован? Это странно. Я их инициализировал, и они должны появиться среди местных. Я бы передал вам скриншот казни, но у меня пока недостаточно прав :(
Было бы полезно, если бы вы также предоставили header_C.hpp.