Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;20在先前的类型参数中为模板的非类型模板参数:不是有效的模板参数,因为不是变量_C++_Templates_C++20 - Fatal编程技术网

C++ C++;20在先前的类型参数中为模板的非类型模板参数:不是有效的模板参数,因为不是变量

C++ C++;20在先前的类型参数中为模板的非类型模板参数:不是有效的模板参数,因为不是变量,c++,templates,c++20,C++,Templates,C++20,我已经被这个问题难住了一段时间,并总结了一个简单的错误消息示例。有什么办法可以让它工作吗?我只是缺少了一个“模板”或“类型名”吗 #include <cstdint> template<typename T, typename J> struct silly { const void (*f)(T,J); }; template<typename T, typename J, silly<T, J> aSilly> struct sil

我已经被这个问题难住了一段时间,并总结了一个简单的错误消息示例。有什么办法可以让它工作吗?我只是缺少了一个“模板”或“类型名”吗

#include <cstdint>

template<typename T, typename J>
struct silly
{
    const void (*f)(T,J);
};

template<typename T, typename J, silly<T, J> aSilly>
struct sillier
{
    const uint32_t something;
};

void dumb_func(uint32_t i, uint32_t j)
{
    return;
}

constexpr silly<uint32_t, uint32_t> mySilly{ .f = dumb_func };

using silliest = sillier<uint32_t, uint32_t, mySilly>;

int main()
{
    return 2;
}
#包括
模板
愚蠢的结构
{
常量无效(*f)(T,J);
};
模板
结构筛
{
保持某事;
};
无效哑函数(uint32\u t i,uint32\u t j)
{
返回;
}
constexpr silly mySilly{.f=dumb_func};
使用最愚蠢的=更愚蠢的;
int main()
{
返回2;
}
g++吐出:

g++ -std=c++2a ugh.cpp

ugh.cpp:20:51: error: invalid conversion from ‘void (*)(uint32_t, uint32_t)’ {aka ‘void (*)(unsigned int, unsigned int)’} to ‘const void (*)(unsigned int, unsigned int)’ [-fpermissive]
   20 | constexpr silly<uint32_t, uint32_t> mySilly{ .f = dumb_func };
      |                                                   ^~~~~~~~~
      |                                                   |
      |                                                   void (*)(uint32_t, uint32_t) {aka void (*)(unsigned int, unsigned int)}
ugh.cpp:20:51: error: ‘dumb_func’ is not a valid template argument of type ‘const void (*)(unsigned int, unsigned int)’ because ‘dumb_func’ is not a variable
g++-std=c++2a ugh.cpp
ugh.cpp:20:51:错误:从'void(*)(uint32_t,uint32_t){aka'void(*)(无符号整数,无符号整数)}到'const void(*)(无符号整数,无符号整数)[-fpermissive]的转换无效
20 | constexpr silly mySilly{.f=dumb_func};
|                                                   ^~~~~~~~~
|                                                   |
|void(*)(uint32_t,uint32_t){aka void(*)(无符号整数,无符号整数)}
ugh.cpp:20:51:错误:“dumb_func”不是类型为“const void(*)(unsigned int,unsigned int)”的有效模板参数,因为“dumb_func”不是变量
我试着通读,但我的模板深度不够。实际的使用案例是T和J类似于std::array,然后sillier继承自其他更一般的类,并具有重写,这些重写调用f等函数,以便所有内容都内联到特定的函数中,用于给定的Styly实例。

编辑:

sillier
的第三个模板参数是非类型模板参数,它只能绑定到变量,但
dumb_func
不是变量

这个解释没有意义,事实上代码可能很好,错误可能只是在本文中发现和报告的错误。下面给出的修复仍然有效


可以将第三个模板参数设置为引用类型的非类型模板参数

template<typename T, typename J, silly<T, J> const & aSilly>
                                          // ^^^^^^^
struct sillier
{
    const uint32_t something;
};
因此,您需要从
f
的返回类型中删除
const
,或者可以更改
dumb_func
的声明以返回
const void
类型:

const void (*f)(T,J);
const void dumb_func(uint32_t i, uint32_t j)
{
    return;
}
const void
返回函数中似乎没有任何点,所以我选择第一个选项



这里有一个。

这与
愚蠢的
作为模板毫无关系。有趣。但是由于删除最后一行解决了这个问题,它确实与它是一个非类型模板参数有关。
cdecl:explain const void(*f)(T,J);=>将f声明为返回常量void的函数(T,J)的指针。。。解释无效(*常数f)(T,J);=>将f声明为返回void的函数(T,J)的常量指针——该常量是否应该在内部?是的,请参见下面的注释。Thanks@AlexanderSugar没问题:)我明白你为什么现在这么做了。是的,将const放在正确的位置可能很棘手,这一直让我困惑:p Try,在这些情况下它很有用。尽管我实际上仍然感到困惑:你说第三个参数是一个非类型模板参数,因此我们无法将dumb_func绑定到它,但我没有尝试绑定dumb_func,我是在尝试绑定mySilly,对吗?这也是让我对错误消息感到困惑的原因。。。这与参数与参数有关吗?@AlexanderSugar好的,现在我甚至不确定是否需要我的修复。clang很乐意接受您的代码:((在您解决了
f
const
问题之后)。所以这可能是gcc/clang的错误。gcc诊断有点奇怪。@Alexander Sugar,我明白了。clang 11.0不支持:)只需使用主干编译即可。