C++ 如何在虚拟方法中处理实例化?
我有一个可变类模板,它有一个虚拟函数。此函数使用C++ 如何在虚拟方法中处理实例化?,c++,c++11,C++,C++11,我有一个可变类模板,它有一个虚拟函数。此函数使用Ts..之一的方法 我希望bar()函数仅在Ts..具有baz()时实例化。当前,编译器实例化函数并报告一个错误,x没有函数baz()。因为虚拟函数不能是模板,所以我无法解决这个问题 template <class... Ts> struct Foo { static constexpr auto I = 2; virtual void bar() { auto x = std::get<
Ts..
之一的方法
我希望bar()
函数仅在Ts..
具有baz()
时实例化。当前,编译器实例化函数并报告一个错误,x
没有函数baz()
。因为虚拟函数不能是模板,所以我无法解决这个问题
template <class... Ts>
struct Foo
{
static constexpr auto I = 2;
virtual void bar()
{
auto x = std::get<I>(std::make_tuple(Ts::create()...));
x.baz();
}
};
模板
结构Foo
{
静态constexpr auto I=2;
虚拟空心条()
{
auto x=std::get(std::make_tuple(Ts::create()…);
x、 baz();
}
};
有什么办法可以解决这个问题?我知道我可以通过将工作传递给一个helper类来进行专门化,Foo
从中派生,将类型存储在一个基于条件的元组中,如果Ts…
具有baz()
,但我不想引入另一个间接级别。还有其他选择吗
更新:我将调用经典的“has member”技巧(请原谅,我忘了我第一次在哪里看到它) 我已经说服VS2013,这是可以的:
template<typename T>
struct HazBaz
{
struct YesSir{char y[2];};
struct NoSir{char y;};
template<typename A>
static auto Frob(A &&a) ->
typename std::enable_if<
std::is_same<decltype(a.baz()), decltype(a.baz())>::value,
YesSir
>::type;
static NoSir Frob(...);
static const bool value =
sizeof(Frob(declval<T>())) == sizeof(YesSir);
};
template<typename T0, typename ...TN>
struct AllHazBaz
{
static const bool value =
HazBaz<T0>::value &&
AllHazBaz<TN...>::value;
};
template<typename T>
struct AllHazBaz<T>
{
static const bool value = HazBaz<T>::value;
};
template<bool implementBar, typename ...Ts>
struct FooBase
{
// Assuming that we do
virtual void bar()
{
// Do the things here
}
};
template<typename ...Ts>
struct FooBase<false, Ts...>
{
// Look ma, no bar!
};
template<typename ...Ts>
struct Foo : FooBase<AllHazBaz<Ts...>::value, Ts...>
{
};
模板
哈兹巴兹结构
{
结构YesSir{char y[2];};
结构NoSir{char y;};
模板
静态自动翻页(A和A)->
typename std::启用\u如果<
std::值是否相同,
耶塞尔
>::类型;
静态噪声干扰(…);
静态常数布尔值=
sizeof(Frob(declval())==sizeof(YesSir);
};
模板
阿尔哈兹巴兹结构
{
静态常数布尔值=
HazBaz::值&&
AllHazBaz::值;
};
模板
阿尔哈兹巴兹结构
{
静态常量布尔值=HazBaz::值;
};
模板
结构FooBase
{
//假设我们有
虚拟空心条()
{
//在这里做事
}
};
模板
结构FooBase
{
//看,妈妈,没有酒吧!
};
模板
结构Foo:FooBase
{
};
编辑:Derp。把问题再读一遍。老实说,如果没有继承,我不知道这怎么可能。谁是
I
?你能给出一个完整的例子吗?@KerrekSB把我的答案留在这里,我不知道如何避免继承。但是,我不确定您在哪里需要另一个级别的间接寻址(是否baz
实际上应该有参数?)。也许更大的图景会有所帮助。我可以想到一些只使用专门化的东西,但这需要让Foo
使用tuple
(或类似)而不是直接使用包。您的示例看起来很棒!我对继承很满意,我只是想看看是否还有其他方法。std::is_same
在我看来很奇怪。是否确实要在两个参数中检查相同的decltype
?也许应该使用std::is\u member\u function\u pointer()
而不是std::is\u same
?这是一件非常重要的事情。它允许我将bool
放在enable\u if
中,而不会导致VS爆炸。请注意,如果baz
是一个静态成员,这也适用。VS是否在std::is_member_function_pointer
上爆炸<代码>标准::如果,则启用。我自己从来没有使用过SFINAE,很难理解它的用法。@debube而不是奇怪的is\u same
invocation,你不能定义template struct always\u true:std::true\u type{}代码>?