C++ 对C++;基类

C++ 对C++;基类,c++,c++11,C++,C++11,我试图创建一个可变模板类,它为类型列表中的每个类提供一个方法。下面显示了一个示例,该示例为typelist中的每个类创建一个print方法: #include <iostream> #include <string> // Helper class providing a function call template <typename T> class PrintHelper { public: void print(const T& t)

我试图创建一个可变模板类,它为类型列表中的每个类提供一个方法。下面显示了一个示例,该示例为typelist中的每个类创建一个
print
方法:

#include <iostream>
#include <string>

// Helper class providing a function call
template <typename T>
class PrintHelper
{
public:
    void print(const T& t) { std::cout << t << std::endl; }
};

// Provides a print method for each type listed
template <typename... Ts>
class Printer : public PrintHelper<Ts>...
{};

int main()
{
    Printer<int, std::string> p;
    p.print(std::string("Hello World")); // Ambiguous Call
}
#包括
#包括
//提供函数调用的Helper类
模板
类PrintHelper
{
公众:

void print(const T&T){std::cout要解决歧义,可以

template <typename... Ts>
struct Printer : PrintHelper<Ts>...
{
    template <typename U>
    void print (const U& t)
    {
        PrintHelper<U>::print (t);
    }
};
其中,
find_convertible

template <typename U, typename... Ts>
struct find_convertible
{};

template <typename U, typename V, typename... Ts>
struct find_convertible<U, V, Ts...> :
    std::conditional<
        std::is_convertible<U, V>::value, 
        std::common_type<V>, // Aka identity
        find_convertible<U, Ts...>
    >::type
{};
模板
结构查找可转换
{};
模板
结构查找可转换:
条件的<
std::是否可转换::值,
std::common_类型,//Aka标识
寻找可转换的
>::类型
{};

(请参阅)

以下代码可以解决歧义问题:

#include <iostream>
#include <string>

// Helper class providing a function call
template <typename T>
class PrintHelper
{
  protected:
    void print_impl(const T& t) { std::cout << t << std::endl; }
};

// Provides a print method for each type listed
template <typename... Ts>
class Printer : public PrintHelper<Ts>...
{
  public:
    template <typename U>
    void print(const U& u) { 
      PrintHelper<U>::print_impl(u); 
    };
};

int main()
{
    Printer<int, std::string> p;
    p.print(std::string("Hello World")); // Ambiguous Call
}
#包括
#包括
//提供函数调用的Helper类
模板
类PrintHelper
{
受保护的:

无效的PrtutIMPL(const t&t){STD::CUT< P>我不喜欢回答我自己的问题,但是我已经从下面的注释中创建了下面的解决方案。它把所有的<代码>打印< /代码>函数放入范围内,并允许对所有函数进行C++重载解析。
#include <iostream>
#include <string>

// Helper class providing a function call
template <typename T>
class PrintHelper
{
public:
    void print(const T& t) { std::cout << t << std::endl; }
};

// Provides a print method for each type listed
template <typename... Ts>
class Printer
{};

template<typename T>
class Printer<T> : public PrintHelper<T>
{
public:
    using PrintHelper<T>::print;
};

template<typename T, typename... Ts>
class Printer<T, Ts...>: public PrintHelper<T>, public Printer<Ts...>
{
public:
    using PrintHelper<T>::print;
    using Printer<Ts...>::print;
};

int main()
{
    Printer<int, std::string> p;
    p.print("Hello World"); // Not an ambiguous Call
}
#包括
#包括
//提供函数调用的Helper类
模板
类PrintHelper
{
公众:

无效打印(常量T&T){std::与gcc 4.7.2(at)的问题相同。感谢您提供的复制/可复制示例btw.clang 3.2 trunk 165721说:
错误:在不同类型的多个基类中找到成员“print”
另请参见。这本质上是一个隐藏规则组合的问题,而且解包可变模板参数的能力非常有限。@MikaelPersson:非常感谢您的帮助链接到引用标准的答案。但是,它明确指出,问题与变量模板参数的解包无关(问题是使用父类的显式列表,问题是相同的)。感谢您的帮助。第一个示例对于我的用例来说已经足够了。根据上面的一条评论,还有另一个通过更改继承()来允许转换的潜在解决方案这将使用C++中的超载解析度来解决你的方法,它将在类型化中使用第一个可转换类型。@彼得罗顿:我更喜欢你的其他方法。你能把它作为一个答案来作为将来的参考吗?在线巴氏存储器不会永远持续下去。对这个工具的使用的热爱。+ 1,那太好了,为什么我没有呢?关于这一点,我想这就是你如何解包变量模板的使用声明。回答你自己的问题(甚至明确鼓励)是非常好的。这对未来的读者是有益的。Cf。此外,你提出的解决方案应该是imho接受的。
struct IntPrinter {
  void print(const int& i) { std::cout << i << std::endl; };
};

struct StringPrinter {
  void print(const std::string& s) { std::cout << s << std::endl; };
};

struct IntStringPrinter : IntPrinter, StringPrinter {
  using IntPrinter::print;       // These using-statements will solve the problem
  using StringPrinter::print;    // by importing all 'print' functions to the same 
                                 // overload resolution level.
};
#include <iostream>
#include <string>

// Helper class providing a function call
template <typename T>
class PrintHelper
{
public:
    void print(const T& t) { std::cout << t << std::endl; }
};

// Provides a print method for each type listed
template <typename... Ts>
class Printer
{};

template<typename T>
class Printer<T> : public PrintHelper<T>
{
public:
    using PrintHelper<T>::print;
};

template<typename T, typename... Ts>
class Printer<T, Ts...>: public PrintHelper<T>, public Printer<Ts...>
{
public:
    using PrintHelper<T>::print;
    using Printer<Ts...>::print;
};

int main()
{
    Printer<int, std::string> p;
    p.print("Hello World"); // Not an ambiguous Call
}