实现文件中带有模板参数的方法声明

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(),因为它不符合要求。