我正在開發一個程式,其中一些資料是靜態分配的,一些是動態分配的。現在我想要另一種可以使用該型別的任何模板作為引數呼叫的型別。
#include <array>
#include <vector>
template <int size> class Foo {
std::array<int, size> data;
public:
int& operator[](std::size_t idx) {return data[idx];}
};
template <> class Foo<-1> {
std::vector<int> data;
public:
int& operator[](std::size_t idx) {return data[idx];}
};
// option 1- polymorphism
struct FooCaller {
virtual void operator()(Foo data) = 0; // how would I make this work with both forms of Foo?
};
// option 2- generic programming
template <class T> concept CanCallFoo = requires (const T& t) {
t(std::declval<Foo&>()); // how do I ensure that this can call any overload of Foo?
};
兩種方法都可以,但我不知道該怎么做。因為完整的代碼更復雜,我不想讓兩個 Foo 都從一個基類繼承。
uj5u.com熱心網友回復:
一個 callableF可以寫一個限制,它可以被呼叫,Foo<x>這樣任意函式x必須為真才能有效。
為了使您的“可以使用任何Foo”測驗作業,您必須在編譯時反轉任意函式。
除了檢查 的所有 2^32 個可能值之外,沒有實用的方法可以做到這一點x。不完全是。您遇到的問題是該型別F可能過于強大,您無法確定其屬性。這與 Halt 和 Rice 定理以及模板元編程和 C 多載決議是圖靈完備的這一事實有關(僅相關,因為 2^32 是有限的)。
在另一種情況下,您可以鍵入擦除。撰寫一個可以從任何型別構造的型別RefAnyFoo/并“型別擦除”您想要的操作,例如型別擦除的方式。它可以回避型別或實際上限制為由模板制作的型別的實體。AnyFooValueFoostd::function<void(int)>Foo
那么你的界面是一個帶有AnyFooValue/ 的界面RefAnyFoo(取決于你是在談論副本還是參考)。
現在,把這個翻過來,你可以寫一個接受Ftake的概念RefFooAny。這不是您所要求的,但您可能有 X/Y 問題;你遇到了一個真正的問題,提出了不完整的解決方案,然后詢問如何讓你的解決方案起作用,而不是最初的問題。
同樣,您可能只關心某些ducktype 屬性Foo<?>而不關心特定型別。然后,您的可呼叫物件可以使用檢查這些鴨子型別的概念;這再次 deosn 不能解決您的問題,就像它顛倒它一樣,因為您無法驗證可呼叫物件是否接受來自可呼叫物件外部的整個概念。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/366260.html
下一篇:C 多型和模板化介面
