为什么包含标题导致“在扣除自动之前使用auto”错误?

时间:2017-05-25 19:39:35

标签: c++ templates operator-overloading header-files auto

我参与了我正在进行的项目,并将其缩短为三个简短的文件,复制正在发生的事情。我正在使用2011年标准下使用g ++的Code :: Blocks IDE。

文件为main.cppthing.cppthing.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标题时更改代码以消除此错误?

提前致谢。

1 个答案:

答案 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);
}