实现文件中带有模板参数的方法声明
Declaration of methods with template arguments in implementation file
是否有可能在不同的地方将 class 方法的定义和声明与模板参数(尤其是在使用 constexpr
函数时使用)分开?因为 "template arguments" 不像模板函数的显式特化吗?
或者这种情况是否与已经讨论得很好的话题纠缠在一起:
Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?
Why can templates only be implemented in the header file?
例如:
头文件"someHeader.h"
#include <iostream>
#pragma once
class cc
{
public:
cc()=default;
~cc()=default;
template<uint32 f_val2Check_u32>
constexpr uint32 isPowerOf2();
private:
};
然后是*.cpp文件:
// cpp-file
#include "someHeader.h"
template<uint32 val>
constexpr uint32 cc::isPowerOf2()
{
return ((val&(val-1))==0);
}
编译器必须知道函数在所有使用它的翻译单元中的实现。 constexpr
关键字告诉编译器在编译时计算给定参数的函数结果并传播该值。没有实施,这是无法实现的。
这适用于非模板非 constexpr 函数,因为该值可以在 运行 时间计算,即在链接之后。
问题是模板是在编译时实例化的。
因此需要查看函数的定义或 class 以了解所有 class 操作 将应用于传递的类型.
让我们在函数声明中说:
template <typename T> void print_square(T t)
通过看到这个你能说出什么:
"What all operations are going to be applied on the type T
" ?
老实说,没什么。
现在让我们看一下函数定义:
template <typename T>
void print_square(T t)
{
std::cout << t * t;
}
现在,当我们看到函数定义时,我们可以看出二元运算符 *
应该适用于类型 T
。
这是传递给模板的 类型 的 要求。
换句话说,class 操作 适用于正在传递的类型 T
。
因此,编译器需要访问函数模板的函数定义。
它可以阻止您将 std::string
作为参数传递给 print_square()
,因为它不符合要求。
是否有可能在不同的地方将 class 方法的定义和声明与模板参数(尤其是在使用 constexpr
函数时使用)分开?因为 "template arguments" 不像模板函数的显式特化吗?
或者这种情况是否与已经讨论得很好的话题纠缠在一起: Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?
Why can templates only be implemented in the header file?
例如: 头文件"someHeader.h"
#include <iostream>
#pragma once
class cc
{
public:
cc()=default;
~cc()=default;
template<uint32 f_val2Check_u32>
constexpr uint32 isPowerOf2();
private:
};
然后是*.cpp文件:
// cpp-file
#include "someHeader.h"
template<uint32 val>
constexpr uint32 cc::isPowerOf2()
{
return ((val&(val-1))==0);
}
编译器必须知道函数在所有使用它的翻译单元中的实现。 constexpr
关键字告诉编译器在编译时计算给定参数的函数结果并传播该值。没有实施,这是无法实现的。
这适用于非模板非 constexpr 函数,因为该值可以在 运行 时间计算,即在链接之后。
问题是模板是在编译时实例化的。
因此需要查看函数的定义或 class 以了解所有 class 操作 将应用于传递的类型.
让我们在函数声明中说:
template <typename T> void print_square(T t)
通过看到这个你能说出什么:
"What all operations are going to be applied on the type T
" ?
老实说,没什么。
现在让我们看一下函数定义:
template <typename T>
void print_square(T t)
{
std::cout << t * t;
}
现在,当我们看到函数定义时,我们可以看出二元运算符 *
应该适用于类型 T
。
这是传递给模板的 类型 的 要求。
换句话说,class 操作 适用于正在传递的类型 T
。
因此,编译器需要访问函数模板的函数定义。
它可以阻止您将 std::string
作为参数传递给 print_square()
,因为它不符合要求。