我有一個模板方法,旨在與一組特定的類一起工作。由於我沒有真正需要運行時多態性,所以我決定不使用指向父類的指針,而是讓編譯器將所有內容放在一起。製作一個模板接受一個特定的班級/班級系列?
我想要麼限制可傳遞到模板中的類型,或者當一個不正確的類型傳遞讓GCC問題明智的錯誤。
這可能嗎?
我有一個模板方法,旨在與一組特定的類一起工作。由於我沒有真正需要運行時多態性,所以我決定不使用指向父類的指針,而是讓編譯器將所有內容放在一起。製作一個模板接受一個特定的班級/班級系列?
我想要麼限制可傳遞到模板中的類型,或者當一個不正確的類型傳遞讓GCC問題明智的錯誤。
這可能嗎?
是。根據當天的具體需求,可以使用多種不同的技術。有boost :: enable_if。有MPL和static_assert ...(如果不使用C++ 0x編譯器,請使用BOOST_STATIC_ASSERT)。有Boost.Concepts。
是的。有可能的。
在另一方面,你也不能使用模板。
假設您希望該方法僅在Car
和Dog
上運行。顯然這兩者完全不相關......但他們仍然可以移動。
// move.h
#include <boost/variant.hpp>
class Car;
class Dog;
typedef boost::variant<Car*,Dog*> move_type;
void move(move_type m);
// move.cpp
#include <boost/apply_visitor.hpp>
#include "car.h"
#include "dog.h"
#include "move.h"
struct Mover: boost::static_visitor<>
{
void operator()(Car* c) const { c->advance(); }
void operator()(Dog* d) const { d->run(); }
};
void move(move_type m)
{
boost::apply_visitor(Mover(), m);
}
而這比一個典型的模板甚至更好,因爲實行的是源文件:在
你可以不喜歡什麼馬修說,寫出來單獨的函數爲每個支持類型(它仍然可以在後端調用模板函數),或者使用動態多態和繼承。這些應該是你應該考慮做你想做的唯一選擇。
但是,你問這個問題使我相信這是模板和靜態多態性的誤解。函數/類模板通過生成的實際代碼對可以使用的類型施加限制。在這些函數/類中使用的公共接口定義了可接受類型的約束。沒有必要不必要地施加額外的限制。爲什麼要限制類/函數模板可以支持的類型比已經放置的限制更多?
比方說,你寫一個函數模板,只能實現一個公共接口,它由生活存取,一擊殺功能的工種,和吃的功能(基本上任何生物體)。這就是它所放置的約束條件:您不需要通過減少可以與函數模板一起工作的類型數量來限制靈活性,也不需要定義任何可以這種方式工作的特定有機體類型。該模板已經要求實施這個有機體類型的界面。