暂无个人介绍
2020年03月
首先,请参阅 为什么只能在头文件中实现模板(阿里云社区地址)
为什么只能在头文件中实现模板(stackoverflow地址) 现在,您的问题并非来自上述问题,但是,您仍应需要考虑是否要在cpp文件中实现模板。 我怀疑你没有。
无论如何,您要问的问题是您试图定义一个尚未模板特化的专门类模板的方法。
下面有两个选择。 - 您可以特化类模板,重复整个过程
template<typename numberType>
class MyComputationClass<numberType, true>
{
numberType a = 1;
numberType b = 2;
numberType compute();
};
if constexpr
:template<typename numberType, bool increaseByOne>
numberType MyComputationClass<numberType, increaseByOne>::compute()
{
if constexpr (increateByOne)
return a + b + 1;
else
return a + b;
}
template<typename numberType, bool increaseByOne>
class MyComputationClass
{
numberType a = 1;
numberType b = 2;
numberType compute() requires increaseByOne
{
return a + b + 1;
};
numberType compute() requires (!increaseByOne)
{
return a + b;
};
};
回答来源:stackoverflow
警告:没有必要把在头文件中实现它,这个答案的末尾有替代解决方案。
无论如何,您的代码失败的原因是:在实例化模板时,编译器会使用给定的模板参数创建一个新类。例如:
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};
// somewhere in a .cpp
Foo<int> f;
阅读此行时,编译器将创建一个新类(我们称之为FooInt
),其等效于以下内容:
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}
因此,编译器需要访问方法的实现,以使用模板参数(在本例中为int
)实例化它们。 如果不在头文件中实现,则将无法访问它们,因此编译器将无法实例化模板。
常见的解决方案是将模板声明写入头文件中,然后在实现文件(例如.tpp)中实现该类,并在头末尾包含该实现文件。
Foo.h
struct Foo
{
void doSomething(T param);
};
#include "Foo.tpp"
Foo.tpp
void Foo<T>::doSomething(T param)
{
//implementation
}
用这种方式,实现仍与声明分开,但编译器可以访问。
另一个解决方案是使实现分离,并显式实例化您需要的所有模板实例:
Foo.h
template <typename T> struct Foo { ... };
Foo.cpp
// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float
如果我的解释不够清楚,您可以查看有关此主题的C ++ Super-FAQ。
回答来源:stackoverflow
我没有全部检查过,但是我之前遇到过此错误。
在attachA
中,创建一个临时对象并保存其地址。这样做是不行的,因为对象会在方法结束时被破坏。
因此,您有一个地址到达堆栈中的某个位置(因为堆栈局部变量)。 在另一个对象上调用该方法时,堆栈框架偶然(或多或少)是相同的,并且该对象位于同一位置。
因此,两个地址的末尾相同(并且附带无效)。
回答来源:stackoverflow