C++ 是否为模板类的某些模板参数添加成员?

C++ 是否为模板类的某些模板参数添加成员?,c++,templates,c++11,metaprogramming,template-specialization,C++,Templates,C++11,Metaprogramming,Template Specialization,考虑一个模板类: template <class First, class Second, class Third, class Fourth> class MyClass; 它工作得很好,但与其说它是一种干净的/标准的方法,不如说它是一种元编程技巧。我不太明白在您的声明中使用Dummy的目的。可以使用两个默认模板参数来完成,这两个参数在函数参数列表中根本不使用: #include <type_traits> #include <string> templ

考虑一个模板类:

template <class First, class Second, class Third, class Fourth>
class MyClass;

它工作得很好,但与其说它是一种干净的/标准的方法,不如说它是一种元编程技巧。

我不太明白在您的声明中使用Dummy的目的。可以使用两个默认模板参数来完成,这两个参数在函数参数列表中根本不使用:

#include <type_traits>
#include <string>

template <class First> // arguments ommited for brevity
struct MyClass {
    template<
        typename U = First,
        typename = typename std::enable_if< std::is_same<U, std::string>::value >::type
    >
    void f() {}
};

int main()
{
    MyClass<int> c1;
    MyClass<std::string> c2;
    // this is an error
    // c1.f();
    c2.f();    // this works
}

注意有可能作弊:c1.f;仍然有效。

我不太明白你声明中使用Dummy的目的。可以使用两个默认模板参数来完成,这两个参数在函数参数列表中根本不使用:

#include <type_traits>
#include <string>

template <class First> // arguments ommited for brevity
struct MyClass {
    template<
        typename U = First,
        typename = typename std::enable_if< std::is_same<U, std::string>::value >::type
    >
    void f() {}
};

int main()
{
    MyClass<int> c1;
    MyClass<std::string> c2;
    // this is an error
    // c1.f();
    c2.f();    // this works
}

注意有可能作弊:c1.f;仍然有效。

您可以使用继承和专门化。 比如:

template <typename T> struct Helper2 {};

template <> struct Helper2<std::string>
{
    void f() {};
};

template <class First, class Second, class Third, class Fourth>
struct MyClass : public Helper2<Second>
{
    // Normal code.
};

int main()
{
    MyClass<std::string, int, std::string, std::string> c1;
    MyClass<int, std::string, int, int> c2;
    //c1.f();     // this is an error
    c2.f();    // this works
    return 0;
}

您可以使用继承和专门化。 比如:

template <typename T> struct Helper2 {};

template <> struct Helper2<std::string>
{
    void f() {};
};

template <class First, class Second, class Third, class Fourth>
struct MyClass : public Helper2<Second>
{
    // Normal code.
};

int main()
{
    MyClass<std::string, int, std::string, std::string> c1;
    MyClass<int, std::string, int, int> c2;
    //c1.f();     // this is an error
    c2.f();    // this works
    return 0;
}

在C++1y概念中,我们有requires子句,可以让您轻松地完成这项工作。看,我可能错了

在C++1y之外,由于所有函数模板必须至少有一个有效的专门化,您的技术会使您的程序格式不正确,不需要进行诊断。碰巧,这是一个很少强制执行的需求,因为解决一般情况下没有有效的专门化涉及到解决停止问题。尽管如此,程序员仍有责任确保所有模板函数至少有一组有效的模板参数

我发现在C++11中,零参数函数严格合法的方法是使用基于CRTP的类专门化,从而消除了CRTP基专门化中的方法


另一种方法是创建一个私有的、不可访问的类型,并使之成为在您想要禁用它的情况下创建合法专门化的唯一方法。然后私下里,在类内你可以作弊,但在类外你不能作弊。

在C++1y概念中,我们有requires子句,可以让你轻松做到这一点。看,我可能错了

在C++1y之外,由于所有函数模板必须至少有一个有效的专门化,您的技术会使您的程序格式不正确,不需要进行诊断。碰巧,这是一个很少强制执行的需求,因为解决一般情况下没有有效的专门化涉及到解决停止问题。尽管如此,程序员仍有责任确保所有模板函数至少有一组有效的模板参数

我发现在C++11中,零参数函数严格合法的方法是使用基于CRTP的类专门化,从而消除了CRTP基专门化中的方法


另一种方法是创建一个私有的、不可访问的类型,并使之成为在您想要禁用它的情况下创建合法专门化的唯一方法。然后私下里在课堂内你可以作弊,但在课堂外你不能作弊。

虚拟参数的用途与你的U差不多,但要避免作弊。@Vincent我向你致敬,先生:虚拟参数的用途与你的U差不多,但要避免作弊。@Vincent我向你致敬,先生:如果您将C++1y列为选项,那么这是:如果您将C++1y列为选项,那么这是:+1但是,如果您想将其推广到多个基类,那么使用类Helper(B{})是很方便的,尤其是在不总是将EBO用于多重继承的平台上;并使用基类链接。例如MyClass:Helper1{};这将保证单一继承。Boost.Operators使用这种方法,例如+1,但是如果您想将其推广到多个基类,那么使用类Helper:B{}可以很方便,特别是在不总是使用EBO进行多重继承的平台上;并使用基类链接。例如MyClass:Helper1{};这将保证单一继承。运营商使用这种方法,例如。