![](/img/trans.png)
[英]Is it possible to check if a type has been instantiated with a specific template parameter?
[英]Is it possible to use 'if constexpr' to determine if a template function could be instantiated with a particular type parameter?
假設存在以下代碼:
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<T>
是否可以實例化的方式編寫我的if constexpr
表達式,而無需對DoFoo
的實現有任何特殊了解,也無需修改DoFoo
。
我正在嘗試在 C++17 中做到這一點,所以如果 C++20 中有一些東西可以處理這個問題,那會很有趣,但不會解決我的問題。
(另請注意,為了創建一個最小的示例,我假設T
是默認可構造的。我並不真正關心DoFoo(T())
的T()
部分——我正在嘗試確定如果DoFoo<T>
完全可以實例化。)
最終的解決方案是 C++20 concept
,因為老式的 SFINAE 方法有它們的警告。 但是,仍然有編譯器錯誤可能會追捕您。 您可以使用requires
子句作為最終可以評估constexpr bool
的內聯概念:
if constexpr(
requires {
/*do your test declaration s*/
}
)//...rest
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.