C++ 可变参数模板方法特化

标签 c++ c++11 variadic-templates

我有一些可变模板方法,看起来像这样:

    template<typename ... Args>
    void Invoke(const char* funcName, Args ... args) const;

    template<typename ... Args>
    void Invoke(const char* funcName, Args ... args) const
    {
        SPrimitive params[] = { args ... };
        SomeOtherInvoke(funcName, params, sizeof ... (Args));
    }

这里是 SPrimitive - 只是一个简单的结构,带有用于任何原始类型的构造函数。

我想为某个复杂类型再做一个 Invoke 定义。这是我的问题: 是否可以在 C++ 11/14 中进行可变参数模板方法特化? 我的意思是这样的(为简单起见,我的类型将是 int):

    template<int ... Args>
    void Invoke(const char* funcName, Args ... args)
    {
        int params[] = { args ... };
        SomeComplexInvoke(funcName, params, sizeof ... (Args));
    }

这里我想要一个特殊化,它接受任何 int 类型的参数计数,所以我可以这样调用它:

    Invoke("method", 2, 4 ,9);

最佳答案

正如@Jarod42 提到的,它不应该通过特化来完成。在您的示例中,如果所有参数类型都是 int,您需要一些特殊的东西,所以让我们编写一个模板来检查它:

template<typename ref, typename t, typename ...types>
struct all_same {
        static constexpr bool value = std::is_same<ref, t>::value && all_same<ref, types...>::value;
};

template<typename ref, typename t>
struct all_same<ref, t> {
        static constexpr bool value = std::is_same<ref, t>::value;
};

它检查第一个类型参数是否等于所有其他类型参数。然后在 Invoke 中,我们应该根据 args... 类型选择 params 类型:

template<typename ... Args>
void Invoke(const char* funcName, Args ... args)
{
    using params_type = typename std::conditional<all_same<int, Args...>::value, int, SPrimitive>::type;
    params_type params[] = { args ... };
    SomeOtherInvoke(funcName, params, sizeof ... (Args));
}

现在为了演示让我们定义:

struct SPrimitive{
};

void SomeOtherInvoke(const char*, SPrimitive*, size_t) {
        std::cout << "Invoked for SPrimitive\n";
}

void SomeOtherInvoke(const char*, int*, size_t) {
        std::cout << "Invoked for int\n";
}

并调用

Invoke("foo", SPrimitive());
Invoke("foo", SPrimitive(), SPrimitive());
Invoke("foo", 1, 2, 3, 4);

输出是:

Invoked for SPrimitive
Invoked for SPrimitive
Invoked for int

这是你要求的。

关于C++ 可变参数模板方法特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39013244/

相关文章:

c++ - 如何在 Visual Studio 2013+ 中编译包含 "interface"作为变量名的程序

c++ - 错误 C2064 : term does not evaluate to a function taking 0 arguments

c++ - C++11 中字符串文字的 Unicode 编码

c++ - 如何将宏参数转发到格式 func?

c++ - 可以在 C++11 lambda 中隐式捕获参数包吗?

c++ - 从文字字符串推断类型

c++ - 使用 .Net 2.0 C++ 项目的 Build box 需要 VS.Net 2005 吗?

字符串 "M0.89"的 C++ 正则表达式

c++ - 为什么我不能在我的程序中使用 "file_ptr>>variable"从文件中读取?

c++ - 将可变模板类的模板参数解包为常量和常量数组