小编i c*_*ant的帖子

为什么具有无效继承的类型在作为模板参数传递时不会被拒绝?

众所周知,类不能从基本类型和标记为 的类继承final。但尽管如此,下面提供的代码在 Clang 12 和 GCC 9 上编译时没有任何问题。

#include <type_traits>

template<typename T>
struct Inheriter : public T{};

int main()
{
    std::void_t<Inheriter<int>>();
}
Run Code Online (Sandbox Code Playgroud)

c++ metaprogramming template-meta-programming

8
推荐指数
2
解决办法
477
查看次数

为什么具有无效继承的类型不会通过 void_t 获得 SFINAE-out?

假设我们有一个当前类:

template<typename T>
struct Inheriter : public T {};
Run Code Online (Sandbox Code Playgroud)

T请注意,仅当/未声明为时class,其实例化才是格式正确的。structfinal

然后,借助 SFINAE 的强大功能,std::void_t我们可以在编译时检查类型是格式良好还是格式错误。让我们用它来编写我们自己的简单实现std::is_final:

template<typename T, typename = void>
struct IsFinal : public std::true_type{};

template<typename T>
struct IsFinal<T, std::void_t<decltype(Inheriter<T>{})>> : public std::false_type{};
Run Code Online (Sandbox Code Playgroud)

对于任何任意类型,T编译器都应该实例化最专业的版本IsFinal,如果替换失败,则尝试实例化最不专业的版本。并且只有当所有这些都失败时,编译器才必须吐出错误。

但是在 Clang 14 和 GCC 11.2(目前最新的)上,当我们将某种final类型作为模板参数传递给时IsFinal,我们会收到编译错误(https://godbolt.org/z/q8jxP3Thc)。

为什么编译器不尝试实例化最不专业的版本IsFinal,并直接吐出错误?这是编译器错误还是 C++ 语言标准的某些棘手部分?

c++ metaprogramming sfinae language-lawyer template-meta-programming

7
推荐指数
0
解决办法
137
查看次数

C++:如何重写具有相同接口的特定类的方法

我遇到一种情况,我需要从具有相同接口的两个类继承,但要单独覆盖它们,并且我绝对无法调整接口。请参阅下面的代码示例

template<typename T>
struct Foo
{
    virtual ~Foo() = default;
    virtual void foo() = 0;
};

struct Derived : public Foo<int>, public Foo<double>
{
#if 0 // having something like this would be great, but unfortunately it doesn't work
    void Foo<int>::foo() override
    {
        std::cout << "Foo<int>::foo()" << std::endl;
    }

    void Foo<double>::foo() override
    {
        std::cout << "Foo<double>::foo()" << std::endl;
    }
#endif
};
Run Code Online (Sandbox Code Playgroud)

c++ inheritance interface

2
推荐指数
1
解决办法
707
查看次数