如何使用可能不完整的类型参数调用模板函数

问题描述 投票:0回答:1

模板功能

func<T>
设计用于任何地方。对于任何
T
,它都有相同的函数体。 我只想写一次它的主体。但该功能取决于
type<T>
的定义才能正常工作,并且在某些情况下没有
type<T>
的定义。请参阅以下示例(C++17 中):

/// type.h
#include <stddef.h>
#include <stdint.h>

#include <type_traits>

template<typename T, typename = void>
struct type;

template<typename T>
size_t func() {
  return type<T>::magic;
}

template<typename T>
struct type<T, std::enable_if_t<std::is_arithmetic_v<T>>> {
  static constexpr size_t magic = sizeof(T) * 2;
};

/// my_type.h
struct MyStruct {
  int a;

  static void Dummy();
};

/// my_type.cpp
#include "my_type.h"
#include "type.h"

template<>
struct type<MyStruct> {
  static constexpr size_t magic = 123;
};

void MyStruct::Dummy() {
  (void)func<MyStruct>();
}

/// main.cpp
#include "my_type.h"
#include "type.h"

int main(int argc, char **argv) {
  func<int>(); // OK
  func<MyStruct>(); // Error
}

我怎样才能做到这一点

  1. 只写一次
    func<T>
    的正文。
  2. func<T>
    不完整时,可以调用
    type<T>

注意:有一个

Dummy
函数,用于强制编译器为
func<MyStruct>
生成代码,以便链接器满意。

c++ templates c++17 sfinae incomplete-type
1个回答
1
投票

使用显式实例化:

/// my_type.h
struct MyStruct {
  int a;
};

// Explicit instantiation declaration
extern template size_t func<MyStruct>();
/// my_type.cpp
#include "my_type.h"
#include "type.h"

template<>
struct type<MyStruct> {
  static constexpr size_t magic = 123;
};

// Explicit instantiation definition
template size_t func<MyStruct>();

声明它存在于头文件中(因此包含头文件的任何内容都可以看到声明,而不是尝试实例化模板本身),并在类型完成后在源文件中定义它。

您也不再需要

Dummy
,无论如何也不能保证它能工作。

© www.soinside.com 2019 - 2024. All rights reserved.