如果可以使用constexpr'确定是否可以使用特定类型参数实例化模板函数?
假设存在以下代码:
class Foo {
public:
void foo() const { std::cout << "foo" << std::endl; }
};
class Bar {
public:
void bar() const { std::cout << "bar" << std::endl; }
};
template <typename T>
void DoFoo(const T& f) {
f.foo();
}
想编写这样的函数:这
template <typename T>
void DoFooIfPossible() {
if constexpr (/* DoFoo<T>(T()) would compile */) {
DoFoo(T());
} else {
std::cout << "[not possible]" << std::endl;
}
}
:
int main() {
DoFooIfPossible<Foo>();
DoFooIfPossible<Bar>();
}
样
foo
[not possible]
我 dofoo
使用的成员函数使用:
template <typename T, typename = void>
struct IsFooPossible : std::false_type {};
template <typename T>
struct IsFooPossible<
T, std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::foo)>>>
: std::true_type {};
template <typename T>
void DoFooIfPossible() {
if constexpr (IsFooPossible<T>::value) {
DoFoo(T());
} else {
std::cout << "[not possible]" << std::endl;
}
}
但是,我在这里问的问题是:我可以在不对实现dofoo
?。
在现实世界中,dofoo
可能是我不拥有的库函数。它可能会在其模板参数类型t
上放置许多不同的条件,并且这些条件可能会随着时间而变化。因此,在enable_if
我代码中的表达式中复制这些条件不是可行的解决方案。
我想知道是否可以以直接直接测试dofoo&lt&lt; t&gt;
的方式来实例化,是否可以在不具有的情况下实例化,是否可以编写我的。关于
dofoo
的实现的任何特殊知识,而无需修改dofoo
。
我正在尝试在C ++ 17中这样做,因此,如果C ++ 20中有一些可以处理的东西,那将很有趣,但无法解决我的问题。
(还请注意,为了创建一个最小的示例,我假设t
是默认构造的。我并不真正在乎t()
的一部分dofoo(t())
- 我正在尝试确定是否可以实例化dofoo&lt; t&gt;
。
Suppose there exists the following code:
class Foo {
public:
void foo() const { std::cout << "foo" << std::endl; }
};
class Bar {
public:
void bar() const { std::cout << "bar" << std::endl; }
};
template <typename T>
void DoFoo(const T& f) {
f.foo();
}
I want to write a function like this:
template <typename T>
void DoFooIfPossible() {
if constexpr (/* DoFoo<T>(T()) would compile */) {
DoFoo(T());
} else {
std::cout << "[not possible]" << std::endl;
}
}
So that:
int main() {
DoFooIfPossible<Foo>();
DoFooIfPossible<Bar>();
}
compiles and prints:
foo
[not possible]
I know that for this particular example I can implement this in the following way by detecting the presence of the member function that DoFoo
uses:
template <typename T, typename = void>
struct IsFooPossible : std::false_type {};
template <typename T>
struct IsFooPossible<
T, std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::foo)>>>
: std::true_type {};
template <typename T>
void DoFooIfPossible() {
if constexpr (IsFooPossible<T>::value) {
DoFoo(T());
} else {
std::cout << "[not possible]" << std::endl;
}
}
However, the question I am asking here is: Can I implement this without making any assumptions about the implementation of DoFoo
?.
In a real-world scenario, DoFoo
may be a library function that I do not own. It may place many different conditions on its template parameter type T
, and those conditions may change over time. So replicating those conditions in an enable_if
expression in my code is not a viable solution.
I was wondering if it is possible to write my if constexpr
expression in a way that directly tests whether DoFoo<T>
can be instantiated without having any special knowledge of the implementation of DoFoo
, and without modifying DoFoo
.
I'm trying to do this in C++17, so if there's something in C++20 that could handle this, that would be interesting to know but wouldn't solve my problem.
(Also note that for the sake of creating a minimal example, I'm assuming T
is default-constructable. I don't really care about the T()
part of DoFoo(T())
-- I'm trying to determine if DoFoo<T>
can be instantiated at all.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最终的解决方案将是C ++ 20
概念
S,因为老式的Sfinae方法具有警告。但是,仍然有一些编译器错误可能会追捕您。您可以使用
需要
子句作为内联概念,最终可以评估constexpr bool
:The ultimate solution would be C++20
concept
s, because old-school SFINAE methods have their caveats. However there are still compiler bugs that might hunt you down.You can use a
requires
clause as an inline concept which can finally evaluate aconstexpr bool
: