如何使用 SFINAE 根据模板类型禁用类内的函数

Gas*_*sim 1 c++ sfinae

我有一个模板类

template<typename TLoader, typename TCreator>
class ManagerGroup {
public:
  uint32_t loadFromPath(const Path &path) {
    return mLoader.load(path);
  }

  void createFile(uint32_t handle) {
    return mCreator.create(handle);
  }

private:
  TLoader mLoader;
  TCreator mCreator;
};
Run Code Online (Sandbox Code Playgroud)

对于loadFromPath和函数,如果提供的类型名称是;createFile我想禁用它们 std::nullptr_t所以,我可以做这样的事情:

ManagerGroup<FontLoader, std::nullptr_t> fontManager;

// No issues
fontManager.loadFromPath("/test");

// Compilation error
fontManager.createFile(10);

ManagerGroup<std::nullptr_t, MeshCreator> meshManager;

// NO issues
meshManager.createFile(20);

// Throws error
meshManager.loadFromFile("/test");
Run Code Online (Sandbox Code Playgroud)

SFINAE 可以做到这一点吗?

我尝试了以下方法,但无法使其正常工作(基于https://en.cppreference.com/w/cpp/types/enable_if中的示例#5 ):

template<typename = std::enable_if_t<!std::same<TCreator, std::nullptr_t>::value>>
void createFile(uint32_t handle) {
  return mCreator.create(handle);
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 8

为了使 SFINAE 工作,您需要使用正在推导的参数。在你的情况下TCreator已经知道,所以你不能使用它。TCreator您可以通过添加自己的参数并将其默认为like来解决该问题

template<typename T = TCreator,
         std::enable_if_t<!std::is_same_v<T, std::nullptr_t>, bool> = true>
void createFile(uint32_t handle) {
  return mCreator.create(handle);
}
Run Code Online (Sandbox Code Playgroud)

  • 也许还有一个 `std::is_same_v&lt;T, TCreator&gt;` 来防止使用模板类型的非默认值实例化 `createFile` (3认同)