I've taken the project I'm working on and shortened it to three brief files that replicate what's happening. I'm working with the Code::Blocks IDE using g++ under the 2011 standard.
我已经完成了我正在进行的项目,并将其缩短为三个简短的文件,复制正在发生的事情。我正在使用2011年标准下使用g ++的Code :: Blocks IDE。
The files are main.cpp
, thing.cpp
and thing.h
. The header (.h
) has declarations and the source (.cpp
) has implementations. The thing
files define a class Thing
with a template parameter T
. All Thing
does is hold an object of type T
(it basically does nothing).
文件是main.cpp,thing.cpp和thing.h。标头(.h)具有声明,源(.cpp)具有实现。 thing文件使用模板参数T定义一个类Thing。所有Thing都会保存一个类型为T的对象(它基本上什么都不做)。
main.cpp
:
#include <iostream>
#include "thing.h"
int main(){
Thing<int> a(9);
Thing<double> b(3.2);
auto c = a + b;
c.display();
return 0;
}
thing.h
:
#ifndef THING_H
#define THING_H
template<typename T>
class Thing{
private:
T content;
public:
Thing(const T& content);
~Thing(){};
T get_content() const;
void display();
};
template<typename S, typename T>
auto operator+(const Thing<S>& s, const Thing<T>& t);
#endif // THING_H
thing.cpp
:
#include "thing.h"
#include <iostream>
template<typename T>
Thing<T>::Thing(const T& content)
:content(content){}
template<typename T>
void Thing<T>::display(){
std::cout << content << '\n';
}
template<typename T>
T Thing<T>::get_content() const {
return content;
}
template<typename S, typename T>
auto operator+(const Thing<S>& s, const Thing<T>& t){
S s_content = s.get_content();
T t_content = t.get_content();
Thing<typename std::common_type<S, T>::type> sum = s_content + t_content;
return sum;
}
Here's the strange behavior: the code will compile or not depending on the line #include "thing.h"
. Using thing.h
here will not compile, causing an error:
这是奇怪的行为:代码将编译或不编译,具体取决于#include“thing.h”行。在这里使用thing.h将无法编译,导致错误:
error: use of 'auto operator+(const Thing<S>&, const Thing<T>&) [with S = int; T = double]' before deduction of 'auto'
error: invalid use of 'auto'
Changing this line to #include "thing.cpp"
allows the code to compile without problems and functions as intended (it outputs 12.2
to the console).
将此行更改为#include“thing.cpp”允许代码编译没有问题和功能按预期(它输出12.2到控制台)。
My question is: What is the compiler doing differently in the two cases? How can I change the code to eliminate this error when includ
ing the header?
我的问题是:在这两种情况下,编译器的做法有何不同?如何在包含标题时更改代码以消除此错误?
Thanks in advance.
提前致谢。
1 个解决方案
#1
0
Deduced return types were introduced in C++14.
推导出的返回类型是在C ++ 14中引入的。
Coliru reproduces your problem in C++11 mode, but shows the code working in C++14.
Coliru在C ++ 11模式下重现了您的问题,但显示了在C ++ 14中运行的代码。
And, of course, although this wasn't the immediate cause of your problem, it is likely that you will have to move your template definitions into the/a header.
当然,虽然这不是问题的直接原因,但您可能需要将模板定义移动到/ a标头中。
Oh, and here's the minimal testcase you should have been testing with:
哦,这是你应该测试的最小测试用例:
template <typename T>
auto foo(T a)
{
return a;
}
int main()
{
foo(42);
}
#1
0
Deduced return types were introduced in C++14.
推导出的返回类型是在C ++ 14中引入的。
Coliru reproduces your problem in C++11 mode, but shows the code working in C++14.
Coliru在C ++ 11模式下重现了您的问题,但显示了在C ++ 14中运行的代码。
And, of course, although this wasn't the immediate cause of your problem, it is likely that you will have to move your template definitions into the/a header.
当然,虽然这不是问题的直接原因,但您可能需要将模板定义移动到/ a标头中。
Oh, and here's the minimal testcase you should have been testing with:
哦,这是你应该测试的最小测试用例:
template <typename T>
auto foo(T a)
{
return a;
}
int main()
{
foo(42);
}