【问题标题】:Overload that still compiles if parameter type doesn't exist如果参数类型不存在,重载仍然可以编译
【发布时间】:2021-06-09 22:05:13
【问题描述】:

我有这样的功能:

template <typename T>
void modify(T& x) {
  ...
}

我想为Foo 类型添加一个专门的重载,如下所示:

void modify(Foo& x) {
  ...
}

但是,这会带来一个问题,即如果 Foo 类型不存在,则此定义将无法编译,但我希望在这种情况下仍然可以编译此标头,只是省略了该重载(逻辑上)。毕竟,如果用户没有包含该类型的定义,Foo 重载将毫无用处。

【问题讨论】:

  • 您的应用程序是否允许以某种方式注册该类型?然后它就变成了一件容易的事。否则我认为这是不可行的。
  • 定义__m256i的头文件是否定义了某些东西(可能是包含保护)?如果是这样,您可以#ifdef(喘气)关闭它。不过可能不太便携,
  • 如果此函数位于定义 __m256i 之前的头文件中,则将无法包含重载 如果您希望重载编译/存在,则头文件定义__m256i 必须先包含,不是吗?
  • C++ 没有“如果类型 xxx 存在”结构,不幸的是。它需要编译器支持,但它不存在。
  • this approach 问题是之后你不能实际使用A,只能使用::A:coliru.stacked-crooked.com/a/fd8ebac5cb93a599

标签: c++ c++11 sfinae


【解决方案1】:

一个不可移植的 hackish 解决方案是使用 ifdefs 检查 Foo 标头包含保护(可能会更改,或者它可能正在使用 #pragma once)。这也需要在翻译单元中的标题之前包含 Foo 标题。

template <typename T>
void modify(T& x) {
  ...
}

#ifdef FOO_H
template<>
void modify(Foo &x) {
  ...
}
#endif

如果您可以选择使用源文件,另一个更简洁的选择是在您的标头中转发声明 Foo,然后在修改函数中,调用源文件中定义的另一个函数,该函数具有 Foo 的全部知识:

// your header
template<typename T>
void modify(T &a) {
    ...
}

class Foo;

void modify_foo(Foo &a);

template<>
void modify(Foo &a) {
    modify_foo(a);
}
// some source file
#include "foo.h"

void modify_foo(Foo &a) {
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2019-09-16
    • 2021-10-06
    • 2014-07-31
    • 2015-10-23
    • 2013-03-16
    • 1970-01-01
    相关资源
    最近更新 更多