Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在虚拟方法中处理实例化?_C++_C++11 - Fatal编程技术网

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{}