Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;)

04.08.2015, 19:46. Показов 3419. Ответов 46
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:
a.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef A_H
#define A_H
 
#include <string>
 
class A
{
    std::string str;
public:
    A() = default;
    A(const std::string &);
 
    void swap(A &) noexcept;
};
 
#endif // A_H
a.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "a.h"
#include <utility>
 
A::A(const std::string &s) : str(s)
{}
 
void A::swap(A &other) noexcept
{
    using std::swap;
    swap(str, other.str);
}
 
namespace std
{
 
template <>
void swap(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
 
}
main.cpp
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <utility>
#include "a.h"
 
int main()
{
    A a1("Hello"), a2("world");
    std::swap(a1, a2);
}
Ошибка для специализации: multiple definition of `void std::swap<A>(A&, A&) В чем проблема?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.08.2015, 19:46
Ответы с готовыми решениями:

Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)
Добрый день. Как осуществляется выделения памяти под перегруженный оператор ввода данных в пользовательский тип? Ведь мы заранее не можем...

в чем разница между void f(int &n) и void f(int &&n)
:help:

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

46
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.08.2015, 19:50
Цитата Сообщение от DiffEreD Посмотреть сообщение
Ошибка для специализации: multiple definition of `void std::swap<A>(A&, A&) В чем проблема?
в main.cpp происходит инстанцирование:
void swap(A &lhs, A &rhs);

в a.cpp происходит аналогичное инстанцирование.


попробуйте вынести в a.h:
C++
1
2
3
4
5
6
7
8
9
10
namespace std
{
 
template <> inline
void swap(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
 
}
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.08.2015, 19:54
Цитата Сообщение от DiffEreD Посмотреть сообщение
multiple definition of `void std::swap<A>(A&, A&) В чем проблема?
Одна реализация генерируется <utility>, другая просто лежит в a.cpp (неиспользованная).
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 20:01  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
попробуйте вынести в a.h
Тоже самое, я пробовал.
Цитата Сообщение от castaway Посмотреть сообщение
Одна реализация генерируется <utility>, другая просто лежит в a.cpp (неиспользованная).
Ну так как исправить то?
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.08.2015, 20:09
Цитата Сообщение от DiffEreD Посмотреть сообщение
Ну так как исправить то?
Например перенести это в main.cpp или отдельный заголовок.
C++
1
2
3
4
5
6
7
8
9
10
namespace std
{
 
template <>
void swap(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
 
}
И у меня еще компилятор ругается "has a different exception specifier". Компилируется так:
C++
1
2
3
4
5
template <>
void swap(A &lhs, A &rhs) noexcept(false)
{
    lhs.swap(rhs);
}
0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
04.08.2015, 20:16
DiffEreD, если я правильно понял, вы пытаетесь переопределить шаблон функции из std? Вот он вам и выдает множественное определение.
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.08.2015, 20:20
Цитата Сообщение от Eraston Посмотреть сообщение
DiffEreD, если я правильно понял, вы пытаетесь переопределить шаблон функции из std? Вот он вам и выдает множественное определение.
Компилятор говорит о множественной реализации, а не о множественном определении.
0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
04.08.2015, 20:28
DiffEreD, специализация. Ок. Попробуйте так:
Цитата Сообщение от DiffEreD Посмотреть сообщение
C++
1
2
3
4
5
template <>
void swap<A>(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
MSDN

Добавлено через 4 минуты

Не по теме:

Цитата Сообщение от castaway Посмотреть сообщение
Компилятор говорит о множественной реализации, а не о множественном определении.
Цитата Сообщение от DiffEreD Посмотреть сообщение
multiple definition of `void std::swap<A>(A&, A&)
транслируем: множественное определение void std::swap<A>(A&, A&), компилятор вообще может иногда сообщать немного не о том, о чем нужно

0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 20:30  [ТС]
Цитата Сообщение от castaway Посмотреть сообщение
Например перенести это в main.cpp или отдельный заголовок.
При выносе в main работает, в отдельный заголовок - нет. Ну, а разве это правильно выносить в main?
0
04.08.2015, 20:31

Не по теме:

Цитата Сообщение от Eraston Посмотреть сообщение
транслируем
Постоянно путаю определение с объявлением.

0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 20:33  [ТС]
Цитата Сообщение от Eraston Посмотреть сообщение
void swap<A>(A &lhs, A &rhs)
Да тоже самое
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.08.2015, 20:37
Лучший ответ Сообщение было отмечено DiffEreD как решение

Решение

Цитата Сообщение от DiffEreD Посмотреть сообщение
При выносе в main работает, в отдельный заголовок - нет.
a.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "a.h"
#include <utility>
#include <iostream>
 
A::A(const std::string &s) : str(s)
{}
 
void A::swap(A &other) noexcept
{
    using std::swap;
    swap(str, other.str);
 
    std::cout << "A::swap()\n";
}
a.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef A_H
#define A_H
 
#include <string>
 
class A
{
    std::string str;
public:
    A() = default;
    A(const std::string &);
 
    void swap(A &) noexcept;
};
 
#endif // A_H
b.h
C++
1
2
3
4
5
6
7
8
9
10
namespace std
{
 
template <>
void swap(A &lhs, A &rhs) noexcept(false)//noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
 
}
main.cpp
C++
1
2
3
4
5
6
7
8
#include "a.h"
#include "b.h"
 
int main()
{
    A a1("Hello"), a2("world");
    std::swap(a1, a2);
}
У меня работает.
1
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
04.08.2015, 20:45
DiffEreD, пробуйте так:
C++
1
template <> void swap<A&>(A &lhs, A &rhs);
У меня без амперсанда такая же ошибка. С амперсандом жизнь прекрасна.
Ошибка компилятора C2912
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 20:48  [ТС]
castaway, да, и у меня тоже такой вариант заработал.
Я только спрошу - это такая общая практика реализации специализации swap для всего? В компиляторах тоже так делают?
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
04.08.2015, 20:52
Цитата Сообщение от DiffEreD Посмотреть сообщение
Я только спрошу - это такая общая практика реализации специализации swap для всего? В компиляторах тоже так делают?
Увы, но я любитель, про общую практику ничего сказать не могу, даже если когда-то где-то встречал.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 20:59  [ТС]
Eraston, это тоже не компилируеться:
a.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef A_H
#define A_H
 
#include <string>
 
class A
{
    std::string str;
public:
    A() = default;
    A(const std::string &);
 
    void swap(A &) noexcept;
};
 
namespace std
{
 
template <>
void swap<A&>(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    lhs.swap(rhs);
}
 
}
 
#endif // A_H
a.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "a.h"
#include <utility>
#include <iostream>
 
A::A(const std::string &s) : str(s)
{}
 
void A::swap(A &other) noexcept
{
    using std::swap;
    swap(str, other.str);
    std::cout << "A::swap()\n";
}
main
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <utility>
#include "a.h"
 
int main()
{
    A a1("Hello"), a2("world");
    std::swap(a1, a2);
}


Добавлено через 5 минут
А если перенести в a.cpp, то оно даже и не вызываеться.
0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
04.08.2015, 21:18
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef gre55
#define gre55
#include <utility>
class df425
{
public:
    df425();
    ~df425();
    int l;
};
namespace std{
    template <> inline void swap<df425>(df425& a, df425& b)
    {
        printf("my swap\n");
    }
    
}
#endif
 
//... main.cpp
#include "df425.h"
//...
    df425 fggdsg, oop;
    std::swap(fggdsg,oop);
Вывел он мне-таки my swap. Фишка в очереди подключения utility видимо.

Добавлено через 5 минут
Тоже работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//df425.h
#ifndef gre55
#define gre55
#include <utility>
class df425
{
public:
    df425();
    ~df425();
    int l;
};
namespace std{
    template <> void swap<df425>(df425& a, df425& b);
}
#endif
 
//df425.cpp
#include "df425.h"
df425::df425()
{
}
df425::~df425()
{
}
namespace std{
    template <> void std::swap<df425>(df425& a, df425& b){
        printf("my swap\n");
    }
}
 
//main.cpp
#include "stdafx.h"
#include <memory>
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <string>
#include "df425.h"
#pragma comment(lib,"Winmm.lib")
int main(int argc, _TCHAR* argv[])
{
    df425 fggdsg, oop;
    std::swap(fggdsg,oop);
//...
    return 0;
}
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
04.08.2015, 21:27
Цитата Сообщение от DiffEreD Посмотреть сообщение
это такая общая практика реализации специализации swap для всего?
Используется не специализация шаблона функции, а перегрузка для класса (причем тоже шаблонная). О причинах можно почитать тут.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
04.08.2015, 21:32  [ТС]
Ха, если добавить inline, то все хорошо:
a.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef A_H
#define A_H
 
#include <iostream>
#include <string>
#include <utility>
 
class A
{
    std::string str;
public:
    A() = default;
    A(const std::string &);
 
    void swap(A &) noexcept;
};
 
namespace std
{
 
template <>
inline void swap(A &lhs, A &rhs) noexcept(noexcept(lhs.swap(rhs)))
{
    std::cout << "swap(A &lhs, A &rhs)\n";
    lhs.swap(rhs);
}
 
}
 
#endif // A_H
a.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "a.h"
#include <utility>
#include <iostream>
 
A::A(const std::string &s) : str(s)
{}
 
void A::swap(A &other) noexcept
{
    using std::swap;
    swap(str, other.str);
    std::cout << "A::swap()\n";
}
main
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <utility>
#include "a.h"
 
int main()
{
    A a1("Hello"), a2("world");
    std::swap(a1, a2);
}
вывод
swap(A &lhs, A &rhs)
A::swap()
0
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
04.08.2015, 21:36
Цитата Сообщение от DiffEreD Посмотреть сообщение
Ха, если добавить inline, то все хорошо:
Цитата Сообщение от Eraston Посмотреть сообщение
Ошибка компилятора C2912
Там написано, почему.

Цитата Сообщение от Eraston Посмотреть сообщение
Фишка в очереди подключения utility видимо.
Нельзя создать специализацию шаблона без знания самого шаблона по магии вещей.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.08.2015, 21:36
Помогаю со студенческими работами здесь

В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура x*x+y*y<25&&x*x+y*y>=9&
В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка?
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt; setw(5) &lt;&lt; ptr; // вывод элементов...

Порядок вычисления: операторы «|» и «||», «&» и «&&»
В Java булевые операторы «|» и «||», и «&amp;» и «&amp;&amp;» отличаются друг от друга порядком вычеслений, а в C++ так же как и в Java или...

Parse_matrix(std::istream& in); std::istream& in что это значит?
Есть функция которую необходимо описать: std::pair&lt;int, int&gt; parse_matrix(std::istream&amp; in){ return{ 0,0 }; } Но я не...

Friend ostream& operator<<(ostream& stream, CArr& obj);
CArr.h #pragma once class CArr{ int* arr = nullptr; int size = 10; void swap(int *a, int *b); void swap(int &amp;a, int &amp;b); ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Аутентификация OAuth в Python
py-thonny 22.05.2025
OAuth (Open Authorization) — это целый стандарт для делегированного доступа. Звучит занудно? Давайте проще: OAuth позволяет приложениям получать доступ к информации пользователя на сторонних сервисах. . .
Хеширование и соль паролей в веб-приложениях C#
stackOverflow 22.05.2025
Когда-то в начале своей карьеры я тоже грешил простейшими подходами к хранению паролей – MD5-хеширование казалось верхом защиты. Но технологии не стоят на месте, вычислительные мощьности растут, и. . .
Генераторы Python для эффективной обработки данных
AI_Generated 21.05.2025
В Python существует инструмент настолько мощный и в то же время недооценённый, что я часто сравниваю его с тайным оружием в арсенале программиста. Речь идёт о генераторах — одной из самых элегантных. . .
Чем заменить Swagger в .NET WebAPI
stackOverflow 21.05.2025
Если вы создавали Web API на . NET в последние несколько лет, то наверняка сталкивались с зелёным интерфейсом Swagger UI. Этот инструмент стал практически стандартом для документирования и. . .
Использование Linq2Db в проектах C# .NET
UnmanagedCoder 21.05.2025
Среди множества претендентов на корону "идеального ORM" особое место занимает Linq2Db — микро-ORM, балансирующий между мощью полноценных инструментов и легковесностью ручного написания SQL. Что. . .
Реализация Domain-Driven Design с Java
Javaican 20.05.2025
DDD — это настоящий спасательный круг для проектов со сложной бизнес-логикой. Подход, предложенный Эриком Эвансом, позволяет создавать элегантные решения, которые точно отражают реальную предметную. . .
Возможности и нововведения C# 14
stackOverflow 20.05.2025
Выход версии C# 14, который ожидается вместе с . NET 10, приносит ряд интересных нововведений, действительно упрощающих жизнь разработчиков. Вы уже хотите опробовать эти новшества? Не проблема! Просто. . .
Собеседование по Node.js - вопросы и ответы
Reangularity 20.05.2025
Каждому разработчику рано или поздно приходится сталкиватся с техническими собеседованиями - этим стрессовым испытанием, где решается судьба карьерного роста и зарплатных ожиданий. В этой статье я. . .
Cython и C (СИ) расширения Python для максимальной производительности
py-thonny 20.05.2025
Python невероятно дружелюбен к начинающим и одновременно мощный для профи. Но стоит лишь заикнуться о высокопроизводительных вычислениях — и энтузиазм быстро улетучивается. Да, Питон медлительнее. . .
Безопасное программирование в Java и предотвращение уязвимостей (SQL-инъекции, XSS и др.)
Javaican 19.05.2025
Самые распространёные векторы атак на Java-приложения за последний год выглядят как классический "топ-3 хакерских фаворитов": SQL-инъекции (31%), межсайтовый скриптинг или XSS (28%) и CSRF-атаки. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru