我参与了我正在进行的项目,并将其缩短为三个简短的文件,复制正在发生的事情。我正在使用2011年标准下使用g ++的Code :: Blocks IDE。
文件为main.cpp
,thing.cpp
和thing.h
。标头(.h
)具有声明,源(.cpp
)具有实现。 thing
文件使用模板参数Thing
定义类T
。所有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;
}
这是一个奇怪的行为:代码将编译或不编译,具体取决于行#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'
将此行更改为#include "thing.cpp"
允许代码编译时没有问题和功能按预期(它将12.2
输出到控制台)。
我的问题是:在这两种情况下,编译器的做法有何不同?如何在includ
标题时更改代码以消除此错误?
提前致谢。
答案 0 :(得分:0)
在C ++ 14中引入了推导的返回类型。
Coliru reproduces your problem in C++11 mode,但shows the code working in C++14。
当然,虽然这不是问题的直接原因,it is likely that you will have to move your template definitions into the/a header。
哦,这是你应该测试的 minimal 测试用例:
template <typename T>
auto foo(T a)
{
return a;
}
int main()
{
foo(42);
}