没有明显原因得到 "Multiple definition"
Getting "Multiple definition" with no apparent reason
从标题看问题已经很清楚了。这是代码:
TimeTask.hpp:
#pragma once
#include <locale>
#include <codecvt>
#include <chrono>
namespace TimeTask {
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
std::tm * to_date(
int day, int month, int year,
int hours = -1, int minutes = -1, int seconds = -1
) {
time_t rawTime = time(0);
std::tm * tInfo = localtime(&rawTime);
tInfo->tm_mday = day;
tInfo->tm_mon = month - 1;
tInfo->tm_year = year - 1900;
if(hours >= 0)
tInfo -> tm_hour = hours;
if(seconds >= 0)
tInfo -> tm_sec = seconds;
if(minutes >= 0)
tInfo -> tm_min = minutes;
return tInfo;
}
std::string from_time_point(const std::chrono::system_clock::time_point &arg) {
time_t time = std::chrono::system_clock::to_time_t(arg);
return ctime(&time);
}
}
Task.hpp:
#pragma once
#include <string>
#include "TimeTask.hpp"
class Task
{
public:
Task(
const std::basic_string<wchar_t>&,
const bool&,
const std::chrono::system_clock::time_point&
);
Task();
std::basic_string<wchar_t> description;
bool executed;
std::chrono::system_clock::time_point date;
std::wstring towString();
};
Task.cpp:
#include "Task.hpp"
#include <sstream>
Task::Task(
const std::basic_string<wchar_t>& description,
const bool& executed,
const std::chrono::system_clock::time_point& date
):
description(description),
executed(executed),
date(date) { }
Task::Task():
Task( L"Task", false, std::chrono::system_clock::now() ) { }
std::wstring Task::towString() {
std::wostringstream retval(L"");
retval << L"Task:\t"
<< description
<< L"\nPerformed:\t"
<< std::boolalpha << executed;
retval << TimeTask::converter.from_bytes(TimeTask::from_time_point(date));
return retval.str();
}
main.cpp:
#include <iostream>
#include <type_traits>
#include <vector>
#include <list>
#include "Task.hpp"
int main () {
Task t1(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 5,5,2017)) ));
Task t2(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 1,10,2017)) ));
Task t3(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 1,17,2017 )) ));
std::list <Task> agenda1 = { t1, t2, t3 };
std::vector <Task> agenda2 = { t1, t2, t3 };
for( auto it : agenda1 )
std::cout << TimeTask::converter.to_bytes(it.towString());
return 0;
}
我在这里做错了什么?我没有看到 to_date
和 from_time_point
的任何多重定义(我的编译器 g++
正在抱怨的功能)。
您应该将这些函数标记为 inline
。因为你的头文件不仅声明了,还定义了这个函数。当从多个翻译单元包含时,这两个都会编译该函数的一个实例,并且在链接过程中会出错。
详见一定义规则([basic.def.odr]):
- Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.
The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]).
An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
/../
- There can be more than one definition of a class type, enumeration type, inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
从标题看问题已经很清楚了。这是代码:
TimeTask.hpp:
#pragma once
#include <locale>
#include <codecvt>
#include <chrono>
namespace TimeTask {
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
std::tm * to_date(
int day, int month, int year,
int hours = -1, int minutes = -1, int seconds = -1
) {
time_t rawTime = time(0);
std::tm * tInfo = localtime(&rawTime);
tInfo->tm_mday = day;
tInfo->tm_mon = month - 1;
tInfo->tm_year = year - 1900;
if(hours >= 0)
tInfo -> tm_hour = hours;
if(seconds >= 0)
tInfo -> tm_sec = seconds;
if(minutes >= 0)
tInfo -> tm_min = minutes;
return tInfo;
}
std::string from_time_point(const std::chrono::system_clock::time_point &arg) {
time_t time = std::chrono::system_clock::to_time_t(arg);
return ctime(&time);
}
}
Task.hpp:
#pragma once
#include <string>
#include "TimeTask.hpp"
class Task
{
public:
Task(
const std::basic_string<wchar_t>&,
const bool&,
const std::chrono::system_clock::time_point&
);
Task();
std::basic_string<wchar_t> description;
bool executed;
std::chrono::system_clock::time_point date;
std::wstring towString();
};
Task.cpp:
#include "Task.hpp"
#include <sstream>
Task::Task(
const std::basic_string<wchar_t>& description,
const bool& executed,
const std::chrono::system_clock::time_point& date
):
description(description),
executed(executed),
date(date) { }
Task::Task():
Task( L"Task", false, std::chrono::system_clock::now() ) { }
std::wstring Task::towString() {
std::wostringstream retval(L"");
retval << L"Task:\t"
<< description
<< L"\nPerformed:\t"
<< std::boolalpha << executed;
retval << TimeTask::converter.from_bytes(TimeTask::from_time_point(date));
return retval.str();
}
main.cpp:
#include <iostream>
#include <type_traits>
#include <vector>
#include <list>
#include "Task.hpp"
int main () {
Task t1(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 5,5,2017)) ));
Task t2(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 1,10,2017)) ));
Task t3(L"Lezione programmazione",
false,
std::chrono::system_clock::from_time_t(
std::mktime(TimeTask::to_date( 1,17,2017 )) ));
std::list <Task> agenda1 = { t1, t2, t3 };
std::vector <Task> agenda2 = { t1, t2, t3 };
for( auto it : agenda1 )
std::cout << TimeTask::converter.to_bytes(it.towString());
return 0;
}
我在这里做错了什么?我没有看到 to_date
和 from_time_point
的任何多重定义(我的编译器 g++
正在抱怨的功能)。
您应该将这些函数标记为 inline
。因为你的头文件不仅声明了,还定义了这个函数。当从多个翻译单元包含时,这两个都会编译该函数的一个实例,并且在链接过程中会出错。
详见一定义规则([basic.def.odr]):
- Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
/../
- There can be more than one definition of a class type, enumeration type, inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.