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

时间:2021-10-10 15:08:23

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 including 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);
}