c++ - 启用 C++11 时如何修复 'wrong number of template arguments''?

标签 c++ c++11 templates variadic-templates template-meta-programming

我有一些使用模板的复杂第三方代码。对于 gcc 7.3.0,如果指定了 gcc 标志 -std=gnu++98,它可以正常构建,否则会给出编译错误(即使用 C++11 编译)。我需要修复 C++11 编译。这是代码(抱歉,它不完整,但头文件很复杂):

#define CPP11 (__cplusplus > 199711L)

namespace csl
{
namespace PostExec
{

struct Complement
{
    static int64_t Execute(int64_t v)
    {
        return ~v;
    }
};

template<size_t bitWidth, bool maskOutput>
struct Mask
{
    static int64_t Execute(int64_t v)
    {
        return 0;
    }
};

#if CPP11
template<typename P, typename... PS>
struct Compound
{
    template<typename T>
    static T&& Execute(T&& v)
    {
        if (sizeof...(PS) > 0)
        {
            return Compound<PS...>::Execute(P::Execute(std::forward<T>(v)));    <<<< COMPILER ERROR HERE
        }
        return P::Execute(std::forward<T>(v));
    }
};
#else
template<typename P1, typename P2>
struct Compound
{
    static int64_t Execute(int64_t v)
    {
        return P1::Execute(P2::Execute(v));
    }
};
#endif

}
}

using namespace csl;
class CModel
{
public:

    void f1();

private:
    void Execute() { }

    static const size_t PAGE_COUNT = 1;

    static size_t CurrentPage;
    static CPage<1, 0> State[PAGE_COUNT];
};

void CModel::f1()
{
    int64_t n[5];
    StepLogicalNXOr<1, false>::Execute(Page.N[1], n[0], n[1]);
}

size_t CModel::CurrentPage = 0;

CPage <1919, 0> CModel::State[PAGE_COUNT] = {
    CPage <1, 0>()    
};

编译器错误(定义 CPP11 时)是:

<snip>: error: wrong number of template arguments (0, should be at least 1)
  return Compound<PS...>::Execute(P::Execute(std::forward<T>(v)));
         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<snip>: note: provided for ‘template<class P, class ... PS> struct csl::PostExec::Compound’
struct Compound
       ^~~~~~~~

我知道这很复杂,但如果有人能提供帮助,我将不胜感激。

最佳答案

您尝试过 SFINAE 吗?

我的意思是...(注意:代码未经测试)

template<typename T>
static typename std::enable_if<0 != sizeof...(PS), T&&>::type Execute(T&& v)
{ return Compound<PS...>::Execute(P::Execute(std::forward<T>(v))); }


template<typename T>
static typename std::enable_if<0 == sizeof...(PS), T&&>::type Execute(T&& v)
 { return P::Execute(std::forward<T>(v)); }

我的意思是...您的代码无法正常工作,因为当 sizeof...(PS) == 0

 return Compound<PS...>::Execute(P::Execute(std::forward<T>(v)));

已编译并且 Compound 需要一个或多个模板参数;不能接受零模板参数。

我知道这条线正在测试中

if (sizeof...(PS) > 0)

但是你需要if constexpr

if constexpr (sizeof...(PS) > 0)

避免测试为假时编译;但不幸的是,if constexpr 只能从 C++17 开始使用。

所以我在 C++11 中看到的唯一解决方案是将 Execute() 方法分为两个版本,并根据 sizeof.. 的值启用/禁用第一个或第二个。 .(PS).

关于c++ - 启用 C++11 时如何修复 'wrong number of template arguments''?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53590973/

相关文章:

c++ - 具有数组或 vector 参数的类模板

方法定义中的 C++ 模板参数

c++ - 标准可拨号码格式 (c++ tapi)

java - 如何在 Eclipse 中删除模板

c++ - 包含 Map(具有对象值)和 Multimap(具有 std::string 值)的对象的 boost 序列化:需要什么?

c++ - 有没有办法检测 const 合格对象的构造?

c++11 - 从多个线程调用 boost::asio::io_service run 函数

c++ - 如何制作通用精度 ISO 时间戳生成器

c++ - MFC 单选按钮 - DDX_Radio 和 DDX_Control 行为

c++ - 为什么我的 ifstream 程序以错误的顺序读取单词?