如果我有一个标题foo.h,我将其包含在我的项目中,它的所有内容似乎都可以正常工作:
template<typename T>
void foo(const T param) {
cout << param << endl;
}
Run Code Online (Sandbox Code Playgroud)
但是当我向foo.h添加一个specalization时,我得到一个定义规则(ODR)错误:
template<>
void foo(const bool param) {
cout << param << endl;
}
Run Code Online (Sandbox Code Playgroud)
显然,我可以通过inline专业化来解决这个问题.我的问题是,为什么我需要?如果模板没有违反ODR,为什么要专业化?
c++ inline one-definition-rule template-specialization template-function
考虑以下代码:
template<typename T>
class Base
{
template<typename U>
friend void f(void *ptr) {
static_cast<Base<U>*>(ptr)->run();
}
protected:
virtual void run() = 0;
};
class A : public Base<A>
{
protected:
virtual void run() {}
};
/*
class B : public Base<B>
{
protected:
virtual void run() {}
};
*/
Run Code Online (Sandbox Code Playgroud)
现在可以编译良好(ideone)。但是,如果我取消注释的定义B,那么它将给出以下错误(ideone):
prog.cpp: In instantiation of ‘Base<B>’:
prog.cpp:20: instantiated from here
prog.cpp:6: error: redefinition of ‘template<class U> void f(void*)’
prog.cpp:6: error: ‘template<class U> void f(void*)’ previously defined …Run Code Online (Sandbox Code Playgroud) 此代码将放在头文件中:
template<typename TTT>
inline Permutation<TTT> operator * (const Cycle<TTT>& cy, const Permutation<TTT>& p)
{
return Permutation<TTT>(cy)*p;
}
Run Code Online (Sandbox Code Playgroud)
有inline必要避免链接器错误吗?
如果此函数不是模板并且头文件用于多个.cpp文件,inline则必须避免抱怨函数的多个定义的liker错误.似乎链接器忽略了这个模板.
不确定这两种方式哪个更好(更快):
// first
#define BOUNDED(x,lo,hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
// second
double Bounded(double x, double lo, double hi) {
return fmax(fmin(x, hi), lo);
};
Run Code Online (Sandbox Code Playgroud)
在两者中我都会用它们double.它取决于编译器吗?
我有2个头文件相同的头文件:
template<typename T> inline void func(){
}
Run Code Online (Sandbox Code Playgroud)
我在main.cpp文件中包含这两个头文件然后编译:
g++ main.cpp -o run
Run Code Online (Sandbox Code Playgroud)
但我得到:
In file included from main.cpp:2:0:
test2.cpp:1:34: error: redefinition of ‘template<class T> void func()’
template<typename T> inline void func(){
^
In file included from main.cpp:1:0:
test.cpp:1:34: error: ‘template<class T> void func()’ previously declared here
template<typename T> inline void func(){
Run Code Online (Sandbox Code Playgroud)
如果使用可以重新定义的内联函数,我会得到什么错误?