构造函数中的模板冲突 [英] Template collision in constructors

查看:124
本文介绍了构造函数中的模板冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个定义如下的结构:

  struct A:public B,public C 
{
A(const B& b):B(b),C()
{}

template< typename ... Args>
A(Args& ... args):B(),C(std :: forward< Args>(args)...)
{}
};

int main()
{
B b;

sample1(b);
A sample2(3); //例如,B有一个B(int)构造函数。
}

这不能正常工作,因为 A(b)尝试使用第二个构造函数(非常量引用是首选选项,第一个构造函数是常量引用),但 B 没有任何 B(A&)



此外,我想添加一个 move B的构造函数:

  struct A:public B,public C 
{
A(const B& b):B(b),C()
{}

A(B& b) :move(b)),C()
{}

template< typename ... Args>
A(Args& ... args):B(),C(std :: forward< Args>(args)...)
{}
};

现在,最后一步是融合前两个构造函数:

  struct A:public B,public C 
{
template< typename fw_B>
A(fw_B& b):B(std :: forward< fw_B>(b)),C()
{}

template& Args>
A(Args& ... args):B(),C(std :: forward< Args>(args)...)
{}
};问题:如果第一个版本导致冲突,最后一个版本(我的最终目的)清楚地表明它是一个新的版本。不工作也。

解决方案

一个可能的解决方案是使用 std :: enable_if cppreference.com/w/cpp/types/is_convertiblerel =nofollow> std :: is_convertible 仅包含第一个构造函数,如果参数类型 b 可转换为 B

  template< 
class fw_B,
class = typename std :: enable_if< std :: is_convertible< fw_B,B> :: value,T> :: type>
A(fw_B& b)

例如:

  #include< iostream> 
#include< type_traits>

struct B
{
B(){}
B(int){}
};

struct C {};

struct A:B,C
{
template<
class T,
class = typename std :: enable_if< std :: is_convertible< T,B> :: value,T&
A(T& t){std :: cout<< A(T&)\\\
; }

template< class ... TArgs>
A(TArgs& ... targs){std :: cout< A(TArgs&&)\\\
; }
};

int main()
{
B b;

A a1(b);
A a2(4);
A a3(hello);

return 0;
}

输出:

 
A(T &&)
A(T &&)
A(TArgs &&)



<请参见 http://ideone.com/xJEjic 上的演示。


I have a struct defined as follows:

struct A : public B, public C
{
    A(const B& b) : B(b), C()
    {}

    template<typename... Args>
    A(Args&&... args) : B(), C(std::forward<Args>(args)...)
    {}
};

int main()
{
   B b;

   A sample1(b);
   A sample2(3); // For example, B has a B(int) constructor.
}

And this doesn't work fine, because, A(b) tries use the second constructor (the non-constant reference is the preferred option, and the first constructor is a constant reference), but B hasn't any B(A&).

And moreover, I want to add a move constructor for B:

struct A : public B, public C
{
    A(const B& b) : B(b), C()
    {}

    A(B&& b) : B(std::move(b)), C()
    {}

    template<typename... Args>
    A(Args&&... args) : B(), C(std::forward<Args>(args)...)
    {}
};

Now, the last step is to fusion the first two constructors:

struct A : public B, public C
{
   template<typename fw_B>
   A(fw_B&& b) : B(std::forward<fw_B>(b)), C()
   {}

   template<typename... Args>
   A(Args&&... args) : B(), C(std::forward<Args>(args)...)
   {}
 };

Question: if the first version causes collision, the last version (my final purpose) its clear that it doesn't work also. How could I achieve this goal?

解决方案

A possible solution would be use std::enable_if with std::is_convertible to only include the first constructor if the type of argument b is convertible to B:

template <
  class fw_B,
  class = typename std::enable_if<std::is_convertible<fw_B, B>::value, T>::type>
A(fw_B&& b)

For example:

#include <iostream>
#include <type_traits>

struct B
{
    B() {}
    B(int) {}
};

struct C {};

struct A : B, C
{
    template <
      class T,
      class = typename std::enable_if<std::is_convertible<T, B>::value, T>::type> 
    A(T&& t) { std::cout << "A(T&&)\n"; }

    template <class... TArgs>
    A(TArgs&&... targs) { std::cout << "A(TArgs&&)\n"; }
};

int main()
{
    B b;

    A a1(b);
    A a2(4);
    A a3("hello");

    return 0;
}

Output:

A(T&&)
A(T&&)
A(TArgs&&)

See demo at http://ideone.com/xJEjic .

这篇关于构造函数中的模板冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆