C ++模板推导无法推断模板参数

时间:2016-08-19 07:35:17

标签: c++11 casting template-meta-programming

我有以下情况:

struct AP;
struct B
{
    B() : m(2) {}
    int m;
};

struct A : private B
{
    A() : B(), n(1) {}
private:
    int n;
    friend AP;
};

struct AP
{
    AP(A& a) : a_(a) {}

    template<typename T>
    struct A_B {
        using type = typename std::enable_if< std::is_base_of< typename std::remove_reference<T>::type,
                                                               A >::value,
                                                                    T >::type;
    };

    template<typename T>
    operator typename A_B<T>::type()
    {
        return static_cast<T>(a_);
    }

    template<typename T>
    typename A_B<T>::type get()
    {
        return static_cast<T>(a_);
    }

    int& n() { return a_.n; }
private:
    A& a_;
};

int main()
{
    A a;
    AP ap(a);
    ap.n() = 7;
    const B& b = ap.get<const B&>();
    //const B& b = ap; candidate template ignored: couldn't infer template argument 'T'
    //auto b = static_cast<const B&>(ap); candidate template ignored: couldn't infer template argument 'T'
    std::cout<<b.m;
}

注释行无法编译。 Clang ++注意到“候选模板被忽略:无法推断模板参数'T'”

为什么我无法使用强制转换运算符获取对A的基数的引用? 我认为代码看起来会更好。

2 个答案:

答案 0 :(得分:1)

您发布的答案有效,但除非您确实想要static_assert消息,否则它是过度的。

经典模板在这种情况下运作正常,因为A已经可以转换为B

struct AP
{
    AP(A& a) : a_(a) {}

    template<typename T>
    operator T()
    {
        return a_;
    }

    template<typename T>
    T get()
    {
        return a_;
    }

    int& n() { return a_.n; }
private:
    A& a_;
};

Demo

答案 1 :(得分:0)

我在这里找到答案:http://www.mersenneforum.org/showthread.php?t=18076

这是关键:&#34;当您希望编译器推导出参数类型时,这些类型不能是依赖类型&#34;

用它编译:

<div>
  <img https://pbs.twimg.com/profile_images/604644048/sign051.gif">
  <a class="fb" href=""><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
  <a class="tweeter" href=""><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
</div>

  <div>
  <img https://pbs.twimg.com/profile_images/604644048/sign051.gif">
  <a class="fb" href=""><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
  <a class="tweeter" href=""><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
</div>

  <div>
  <img https://pbs.twimg.com/profile_images/604644048/sign051.gif">
  <a class="fb" href=""><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
  <a class="tweeter" href=""><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
</div>

  <div>
  <img https://pbs.twimg.com/profile_images/604644048/sign051.gif">
  <a class="fb" href=""><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
  <a class="tweeter" href=""><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
</div>