如果可以使用constexpr'确定是否可以使用特定类型参数实例化模板函数?

发布于 2025-01-28 06:21:25 字数 2054 浏览 3 评论 0原文

假设存在以下代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

极致的悲 2025-02-04 06:21:25

最终的解决方案将是C ++ 20 概念 S,因为老式的Sfinae方法具有警告。但是,仍然有一些编译器错误可能会追捕您。
您可以使用需要子句作为内联概念,最终可以评估constexpr bool

if constexpr(
    requires {
        /*do your test declaration s*/
    }
)//...rest

The ultimate solution would be C++20 concepts, 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 a constexpr bool:

if constexpr(
    requires {
        /*do your test declaration s*/
    }
)//...rest
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文