boolc 1 / 1 / 0 Регистрация: 21.09.2017 Сообщений: 31 |
||||||||
1 |
||||||||
12.06.2018, 05:14. Показов 11760. Ответов 4 Метки нет (Все метки)
При компиляции возникает ошибка, в файле mylist.h:
__________________
0 |
zss Модератор 12641 / 10135 / 6102 Регистрация: 18.12.2011 Сообщений: 27,170 |
||||
12.06.2018, 06:42 |
2 |
|||
Решениеclass Node надо вытащить наружу
1 |
1 / 1 / 0 Регистрация: 21.09.2017 Сообщений: 31 |
|
08.07.2018, 17:02 [ТС] |
3 |
class Node надо вытащить наружу Спасибо.
0 |
Croessmah Don’t worry, be happy 17781 / 10545 / 2036 Регистрация: 27.09.2012 Сообщений: 26,516 Записей в блоге: 1 |
||||||||||||||||
08.07.2018, 17:25 |
4 |
|||||||||||||||
«error : declaration of template parameter ‘T’ shadows template parameter» В обоих шаблонах
параметр имеет имя T. Об этом и пишет компилятор. Достаточно просто поменять имя параметра в одном из шаблонов.
Но что-то мне подсказывает, что Вам вообще не нужен шаблонный Node, достаточно простого:
0 |
1 / 1 / 0 Регистрация: 21.09.2017 Сообщений: 31 |
|
08.07.2018, 19:32 [ТС] |
5 |
Надо подумать
0 |
I’m trying to make a graphics program, but I’m having a problem …
My code is the one:
main.cpp:
#include "point_2d.h"
#include <iostream>
int main()
{
cge::point_2d p(5, 5);
p.x = 6;
std::cout << p.x << " " << p.y << std::endl;
std::cin.get();
return 0;
}
point_2d.h:
#ifndef POINT_2D_H
#define POINT_2D_H
namespace cge
{
template<typename T>
struct basic_point_2d
{
typedef T value_type;
constexpr basic_point_2d() noexcept = default;
constexpr basic_point_2d(const basic_point_2d&) noexcept = default;
constexpr basic_point_2d& operator=(const basic_point_2d&) noexcept = default;
template<typename U>
constexpr explicit basic_point_2d(const basic_point_2d<U>&) noexcept; //Conversions
constexpr basic_point_2d(T, T) noexcept; //Constructors
constexpr bool equal(const basic_point_2d&) const noexcept;
template<typename T>
friend constexpr bool operator==(const basic_point_2d<T>&, const basic_point_2d<T>&) noexcept;
template<typename T>
friend constexpr bool operator!=(const basic_point_2d<T>&, const basic_point_2d<T>&) noexcept;
T x = T();
T y = T();
}; //struct basic_point_2d
typedef basic_point_2d<int> point_2d;
typedef basic_point_2d<unsigned> upoint_2d;
} //namespace cge
#endif //POINT_2D_H
point_2d.cpp:
#include "point_2d.h"
template<typename T>
constexpr cge::basic_point_2d<T>::basic_point_2d(T _X, T _Y) noexcept:
x(_X), y(_Y)
{
}
template<typename T>
template<typename U>
constexpr cge::basic_point_2d<T>::basic_point_2d(const basic_point_2d<U>& _Right) noexcept:
x(static_cast<U>(_Right.x)), y(static_cast<U>(_Right.y))
{
}
template<typename T>
constexpr bool cge::basic_point_2d<T>::equal(const basic_point_2d<T>& _Right) const noexcept
{
return(this->x == _Right.x && this->y == _Right.y);
}
template<typename T>
constexpr bool operator==(const cge::basic_point_2d<T>& _Left,
const cge::basic_point_2d<T>& _Right) noexcept
{
return(_Left.equal(_Right));
}
template<typename T>
constexpr bool operator!=(const cge::basic_point_2d<T>& _Left,
const cge::basic_point_2d<T>& _Right) noexcept
{
return(!(_Left == _Right));
}
My makefile looks like this:
test: main.o point_2d.o
g++ main.o point_2d.o -o test
main.o: main.cpp
g++ -c main.cpp -std=c++1z
point_2d.o: point_2d.cpp point_2d.h
g++ -c point_2d.cpp -std=c++1z
And when I compile the program I have these surprises:
In file included from point_2d.cpp:1:
point_2d.h:26:18: error: declaration of template parameter 'T' shadows template
parameter
template<typename T>
^~~~~~~~
point_2d.h:7:14: note: template parameter 'T' declared here
template<typename T>
^~~~~~~~
point_2d.h:29:18: error: declaration of template parameter 'T' shadows template
parameter
template<typename T>
^~~~~~~~
point_2d.h:7:14: note: template parameter 'T' declared here
template<typename T>
^~~~~~~~
mingw32-make: *** [makefile:8: point_2d.o] Error 1
I searched a lot on the internet, but could not find any solution that was satisfactory to the problem.
asked by
anonymous 11.10.2018 / 14:16
Как сказано в следующем фрагменте кода, это обходной путь для gcc 4.4. ошибка, которую я, вероятно, должен удалить сейчас. Увидеть Параметры шаблонов шаблонов и шаблонов с переменными параметрами с помощью gcc 4.4 для фона к этому.
В любом случае это приводит к ошибке в Debian Wheezy с clang 3.4.2-4, перенесенной из нестабильного состояния. Это прекрасно работает с gcc 4.9, также портированной с нестабильной (и 4.7) на Debian Wheezy.
// Workaround for gcc 4.4 bug. See https://stackoverflow.com/q/8514633/350713
template <typename S, typename T,
template <typename S, typename T, typename... Args> class C,
typename... Args>
struct maptype
{
typedef C<S, T, Args...> type;
};
int main(void){}
Ошибка
clang++ -o shadow.ocl -c -ftemplate-depth-100 -fno-strict-aliasing -fno-common -ansi -Wextra -Wall -Werror -Wno-unused-function -Wc++0x-compat -Wpointer-arith -Wcast-qual -Wcast-align -std=c++11 -mtune=native -msse3 -O3 shadow.cc
shadow.cc:3:23: error: declaration of 'S' shadows template parameter
template <typename S, typename T, typename... Args> class C,
^
shadow.cc:2:20: note: template parameter is declared here
template <typename S, typename T,
^
shadow.cc:3:35: error: declaration of 'T' shadows template parameter
template <typename S, typename T, typename... Args> class C,
^
shadow.cc:2:32: note: template parameter is declared here
template <typename S, typename T,
^
2 errors generated.
Я вижу, по крайней мере, пару внешне похожих вопросов по SO, т.е.
Clang VS VC ++:»ошибка: объявление параметра шаблона теней ‘T’» а также
Шаблон C ++, который работал в старом gcc, приводит к ошибке «Параметр шаблона тени» в clang ++
но для меня не очевидно, являются ли они другой проблемой или той же самой проблемой.
Пояснения приветствуются. Я не пишу на C ++ регулярно, и прошло много времени с тех пор, как я смотрел на параметры шаблона шаблона.
2
Решение
Имена S
, T
, Args
в аргументе шаблона шаблона C
template <typename S, typename T, typename... Args> class C
лишние и имеют те же имена, что и S
, T
, Args
от maptype
,
Тот факт, что имена идентичны, приводит к ошибке тени на clang.
Так что вы можете написать
template <typename S,
typename T,
template <typename, typename, typename...> class C,
typename... Args>
struct maptype;
или дать разные имена (для целей документации, поскольку они не могут быть использованы)
template <typename S,
typename T,
template <typename S_Type, typename T_Type, typename... Args_Type> class C,
typename... Args>
struct maptype;
4
Другие решения
- Forum
- General C++ Programming
- declaration of … shadows template parm
declaration of … shadows template parm …
I cannot figure this one out, nor do I understand how to fix it.
My biginteger class is declared thus:
|
|
|
|
|
|
The compiler complains thusly:
In file included from a.cpp:1: bignum.hpp: In function 'std::basic_ostream<_CharT, _Traits>& duthomhas::operator<<(std::basic_ostream<_CharT, _Traits>&, const duthomhas::biginteger_t<AllocT>&)': bignum.hpp:1516: error: expected primary-expression before ',' token bignum.hpp:1516: error: declaration of 'std::basic_string<CharT, TraitsT, std::allocator<_CharT> > TraitsT' bignum.hpp:1509: error: shadows template parm 'class TraitsT' bignum.hpp:1516: error: invalid declarator before '>' token
I’m not sure exactly where I’m crossing names, but I think it has something to do with allowing the biginteger type to be templated…
I’ve tried changing all the stream/string template names, and also the name of my basic_string function, but I get the exact same errors.
Where exactly am I going wrong?
Thank you for reading.
LOL, I think I solved it.
|
|
Naturally, it compiles swimmingly.
I would like to know, if there is one, an answer to the original problem though… What would I have to do to declare my friend insertion operator outside the class’s declaration block?
You’ve got to be kidding me. I didn’t know this «friend defined inside a class» monster. Could you explain what part of the code can see it and use it? Does the code get inlined? What I got from google goes like this: it is defined in the surrounding namespace, but is visible only inside the class.
Anyways, I think what you needed to do in your original code was:
|
|
The type of
n
depends on a template parameter and the compiler assumes that basic_string is a member object that is not a template. Therefore the following
<
is interpreted as the less-than operator. Inside the class, the type of
n
is not anymore dependent on the template parameter, in the sense that the declaration of
n
can be located in the current class template. But I am still learning how those rules work exactly. The explanation I had in my head doesn’t cover this case. I just gave you my intuition.
Regards
Last edited on
simeonz wrote: |
---|
You’ve got to be kidding me. I didn’t know this «friend defined inside a class» monster. Could you explain what part of the code can see it and use it? Does the code get inlined? |
Friend functions can be defined inside template declarations, but it will not get istantiated until
a concrete class of the template is actually created.
here is some info from ‘templates — the complete guide’
However, an interesting effect occurs when a friend function is defined in a class template
because anything that is only declared in a template isn’t a concrete entity until
the template is instantiated. Consider the following example:
|
|
|
|
In this example, two different instantiations create two identical definitions—a direct violation of the ODR (see Appendix A).
We must therefore make sure the template parameters of the class template
appear in the type of any friend function defined in that template
(unless we want to prevent more than one instantiation of a class template
in a particular file, but this is rather unlikely).
Let’s apply this to a variation of our previous example:
|
|
|
|
In this example, every instantiation of Creator generates a different function.
Note that even though these functions are generated as part of the instantiation of a template,
the functions themselves are ordinary functions, not instances of a template.
Also note that because the body of these functions is defined inside a class
definition, they are implicitly inline.
Hence, it is not an error for the same function to be generated in two different translation units.
Woah, that is awesomely cool! I didn’t know about the template qualifier and how it worked like that!
The insertion operator really does not need to be a friend of the class, so I am now using your excellent solution:
|
|
It is legal to define a friend function that way so long as certain conditions are met (mainly, that the class is non-local).
Thank you!
Well guys, I am always happy to learn new aspects. On the other hand, C++ classes are such mix of interface and implementation. Thanks for the info.
Last edited on
Topic archived. No new replies allowed.
I’m trying to do a graphite program, but I’m having a problem…
My code and this:
Main. cpp:
#include "point_2d.h"
#include <iostream>
int main()
{
cge::point_2d p(5, 5);
p.x = 6;
std::cout << p.x << " " << p.y << std::endl;
std::cin.get();
return 0;
}
point_2d.h:
#ifndef POINT_2D_H
#define POINT_2D_Hnamespace cge
{template<typename T> struct basic_point_2d { typedef T value_type; constexpr basic_point_2d() noexcept = default; constexpr basic_point_2d(const basic_point_2d&) noexcept = default; constexpr basic_point_2d& operator=(const basic_point_2d&) noexcept = default; template<typename U> constexpr explicit basic_point_2d(const basic_point_2d<U>&) noexcept; //Conversions constexpr basic_point_2d(T, T) noexcept; //Constructors constexpr bool equal(const basic_point_2d&) const noexcept; template<typename T> friend constexpr bool operator==(const basic_point_2d<T>&, const basic_point_2d<T>&) noexcept; template<typename T> friend constexpr bool operator!=(const basic_point_2d<T>&, const basic_point_2d<T>&) noexcept; T x = T(); T y = T(); }; //struct basic_point_2d typedef basic_point_2d<int> point_2d; typedef basic_point_2d<unsigned> upoint_2d;
} //namespace cge
#endif //POINT_2D_H
point_2d.cpp:
#include "point_2d.h"
template<typename T>
constexpr cge::basic_point_2d<T>::basic_point_2d(T _X, T _Y) noexcept:
x(_X), y(_Y)
{
}template<typename T>
template<typename U>
constexpr cge::basic_point_2d<T>::basic_point_2d(const basic_point_2d<U>& _Right) noexcept:
x(static_cast<U>(_Right.x)), y(static_cast<U>(_Right.y))
{
}template<typename T>
constexpr bool cge::basic_point_2d<T>::equal(const basic_point_2d<T>& _Right) const noexcept
{
return(this->x == _Right.x && this->y == _Right.y);
}template<typename T>
constexpr bool operator==(const cge::basic_point_2d<T>& _Left,
const cge::basic_point_2d<T>& _Right) noexcept
{
return(_Left.equal(_Right));
}template<typename T>
constexpr bool operator!=(const cge::basic_point_2d<T>& _Left,
const cge::basic_point_2d<T>& _Right) noexcept
{
return(!(_Left == _Right));
}
My makefile and so:
test: main.o point_2d.o
g++ main.o point_2d.o -o testmain.o: main.cpp
g++ -c main.cpp -std=c++1zpoint_2d.o: point_2d.cpp point_2d.h
g++ -c point_2d.cpp -std=c++1z
and when I compel the program I have these surprises:
In file included from point_2d.cpp:1:
point_2d.h:26:18: error: declaration of template parameter 'T' shadows template
parameter
template<typename T>
^~~~~~~~
point_2d.h:7:14: note: template parameter 'T' declared here
template<typename T>
^~~~~~~~
point_2d.h:29:18: error: declaration of template parameter 'T' shadows template
parameter
template<typename T>
^~~~~~~~
point_2d.h:7:14: note: template parameter 'T' declared here
template<typename T>
^~~~~~~~
mingw32-make: *** [makefile:8: point_2d.o] Error 1
I looked a lot on the internet, but I couldn’t find any satisfactory solution to the problem.
Проблема с шаблонами. Не понимаю в чем проблема, вроде пол-года назад писал тоже самое и все работало, а сейчас компилятор жалуется (на template… перед class Node…) Visual S вообще не запускает, а online компилятор указывает на эту строку, а именно :
declaration of template parameter ‘T’ shadows template parameter
Не понимаю, что не так, объясните.
template<typename T>
class List {
public:
List();
void push_back(T data);
private:
template<typename T>
class Node {
private:
T data;
Node* pNext;
public:
Node(T data = T(), Node* pNext = nullptr) {
this->pNext = pNext;
this->data = data;
}
};
Node<T>* head;
int Size = 0;
};
template<typename T>
List<T>::List() {
head = nullptr;
Size = 0;
}
template<typename T>
void List<T>::push_back(T data) {
if (head == nullptr) {
head = new Node<T>(T data);
}
else {
Node* current = this->head;
while (current->pNext != nullptr) {
current = current->pNext;
}
current->pNext = new Node<T>(data);
}
Size++;
}
int main()
{
List<int> Data;
}