【发布时间】:2021-07-27 08:51:08
【问题描述】:
我猜任何对 SFINAE 的使用都可能被认为是一种 hack,但在这里我尝试了很长时间,我能做到的最好的方法是在其中一个重载中使用默认的 void* 参数:
struct Dog
{
Dog() {}
void makeNull() {}
};
// If no .makeNull() function this is eliminated
template <typename T>
constexpr auto HasMakeNullFunction() -> decltype(std::declval<T>().makeNull(), bool())
{
return true;
}
// And this one is called. But I could only manage to do it with a default void* p = nullptr
template <typename T>
constexpr bool HasMakeNullFunction(void* p = nullptr)
{
return false;
}
int main()
{
constexpr bool b = HasMakeNullFunction<Dog>(); // True
constexpr bool b2 = HasMakeNullFunction<int>(); // False
}
你应该怎么做?这确实有效,但是使用 SFINAE 的典型方法是使用一个在替换失败时调用的专用版本,对吧?另外,我不喜欢使用默认的 void*,因为我可能会看到误用和隐式转换为 void* 的可能性。
【问题讨论】:
-
你更喜欢哪个版本的 C++?
-
@PatrickRoberts C++17。或者如果 C++20 有更好的解决方案,我也想看看。
-
我不敢说这是 stackoverflow.com/q/257288/1896169 的副本,但这个问题应该有足够的信息来实现
HasMakeNullFunction -
这确实有效它真的不应该。当使用
Dog调用它时,nothings 会阻止 nullptr 版本有效,因此调用是ambiguous。 -
@super 我之所以能这么做,是因为它更喜欢非默认参数版本。没有给出参数,所以首选应该是没有参数的函数。