使用decltype提示不是模板函数的显式专用化?

时间:2022-10-20 22:54:30
今天写了一个测试代码,来巩固decltype和函数模板的知识

template<typename T>
auto f(T& a, T&b)->decltype(a + b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)->decltype(a+b)
{
return a - b;
}

为什么提示
C2912 显式专用化;“double f<double>(double &,double &)”不是函数模板的专用化 ?
因为今天刚刚接触函数模板和decltype,所以不是很熟悉。。

10 个解决方案

#1


这里只是延迟提示返回类型, c++14更加方便了, 大部分情况不用写了,除非多处返回类型不一致需要显式提示

#2


事实上如果只是令专用化函数是decltype则可以编译通过
template<typename T>
T f(T& a, T&b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)->decltype(a+b)
{
return a - b;
}

但是如果令模板函数是decltype则不能通过,同样提示
C2912 显式专用化;“double f<double>(double &,double &)”不是函数模板的专用化 ?
auto f(T& a, T&b)->decltype(a + b)
{
return a + b;
}
template<> double f<double>(double&a, double&b)
{
return a - b;
}

#3


c++98足矣

#4


天!我只是想知道错误原因而不是解决办法。。。。 使用decltype提示不是模板函数的显式专用化?

#5


试了一下.
template<typename T>
auto f(T& a, T&b) ->T
{
    return a + b;
}

template<> auto f<double>(double&a, double&b)
{
    return a - b;
}

不能编译

template<typename T>
auto f(T& a, T&b)
{
    return a + b;
}

template<> auto f<double>(double&a, double&b)
{
    return a - b;
}

能够编译

template<typename T>
auto f(T& a, T&b) ->
{
    return a + b;
}

template<> auto f<double>(double&a, double&b) -> double
{
    return a - b;
}

也能编译

template<typename T>
T f(T& a, T&b)
{
    return a + b;
}

template<> auto f<double>(double&a, double&b) -> decltype(a-b)
{
    return a - b;
}

能编译.

然后其他的几个T与decltype(a+b)互换都不能编译

这水太深了,只有标准帝能解释了

#6


顶楼的应该是能够编译的。你可以去问微软是不是BUG……
至于后面的例子,显然“指定了返回值类型的”与“未指定返回值类型的”两者不能匹配。
匹配失败的具体原因看Clang的编译提示就很明确了。

注意:auto f() -> X跟auto f()是不同的。auto f() -> X最左边的auto只是个 格式要求的占位符(这种格式也只能用auto,不能用其他的),并非“自动推导的那个auto”。
auto f() -> X就相当于X f(),这个X还可以是auto,也可以是decltype(Y),Y还可以是auto。
(原先C++委员会是考虑用 [] f() -> X 这种和lambda统一的形式的,但有一帮“美学家”硬要复用容易混淆的auto……委员会的通病。)

#7


很显然是msvc的bug,或者说是“feature”
换个编译器就好了,如果用的是vs2015可以换clang with microsoft codegen

#8


欲善工事先利其器,别抱着软软的破烂不放,天天纳闷为啥明明正确的东西就是不对。
主楼程序用 gcc 和 clang 都能编译。

#9



auto f(T& a, T&b)->decltype(a + b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)->decltype(a+b)
{
return a - b;
}

int main(int argc, char * argv[]){
double a1=0.7,a2=0.9;
auto r=f(a1,a2);
}

在gcc下可以编译的,VS2015下的确不行
把推导符->去掉,如下代码,VS2015倒是可以编译了,但GCC下却报错了。

template<typename T>
auto f(T& a, T&b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)
{
return a - b;
}

int main(int argc, char * argv[]){
double a1=0.7,a2=0.9;
auto r=f(a1,a2);
}

目前,使用C++11编程不要完全依赖一种编译器。我现在是VS2015和gcc交叉着使用。

#10


一般函数模板不特化,只重载。

#1


这里只是延迟提示返回类型, c++14更加方便了, 大部分情况不用写了,除非多处返回类型不一致需要显式提示

#2


事实上如果只是令专用化函数是decltype则可以编译通过
template<typename T>
T f(T& a, T&b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)->decltype(a+b)
{
return a - b;
}

但是如果令模板函数是decltype则不能通过,同样提示
C2912 显式专用化;“double f<double>(double &,double &)”不是函数模板的专用化 ?
auto f(T& a, T&b)->decltype(a + b)
{
return a + b;
}
template<> double f<double>(double&a, double&b)
{
return a - b;
}

#3


c++98足矣

#4


天!我只是想知道错误原因而不是解决办法。。。。 使用decltype提示不是模板函数的显式专用化?

#5


试了一下.
template<typename T>
auto f(T& a, T&b) ->T
{
    return a + b;
}

template<> auto f<double>(double&a, double&b)
{
    return a - b;
}

不能编译

template<typename T>
auto f(T& a, T&b)
{
    return a + b;
}

template<> auto f<double>(double&a, double&b)
{
    return a - b;
}

能够编译

template<typename T>
auto f(T& a, T&b) ->
{
    return a + b;
}

template<> auto f<double>(double&a, double&b) -> double
{
    return a - b;
}

也能编译

template<typename T>
T f(T& a, T&b)
{
    return a + b;
}

template<> auto f<double>(double&a, double&b) -> decltype(a-b)
{
    return a - b;
}

能编译.

然后其他的几个T与decltype(a+b)互换都不能编译

这水太深了,只有标准帝能解释了

#6


顶楼的应该是能够编译的。你可以去问微软是不是BUG……
至于后面的例子,显然“指定了返回值类型的”与“未指定返回值类型的”两者不能匹配。
匹配失败的具体原因看Clang的编译提示就很明确了。

注意:auto f() -> X跟auto f()是不同的。auto f() -> X最左边的auto只是个 格式要求的占位符(这种格式也只能用auto,不能用其他的),并非“自动推导的那个auto”。
auto f() -> X就相当于X f(),这个X还可以是auto,也可以是decltype(Y),Y还可以是auto。
(原先C++委员会是考虑用 [] f() -> X 这种和lambda统一的形式的,但有一帮“美学家”硬要复用容易混淆的auto……委员会的通病。)

#7


很显然是msvc的bug,或者说是“feature”
换个编译器就好了,如果用的是vs2015可以换clang with microsoft codegen

#8


欲善工事先利其器,别抱着软软的破烂不放,天天纳闷为啥明明正确的东西就是不对。
主楼程序用 gcc 和 clang 都能编译。

#9



auto f(T& a, T&b)->decltype(a + b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)->decltype(a+b)
{
return a - b;
}

int main(int argc, char * argv[]){
double a1=0.7,a2=0.9;
auto r=f(a1,a2);
}

在gcc下可以编译的,VS2015下的确不行
把推导符->去掉,如下代码,VS2015倒是可以编译了,但GCC下却报错了。

template<typename T>
auto f(T& a, T&b)
{
return a + b;
}
template<> auto f<double>(double&a, double&b)
{
return a - b;
}

int main(int argc, char * argv[]){
double a1=0.7,a2=0.9;
auto r=f(a1,a2);
}

目前,使用C++11编程不要完全依赖一种编译器。我现在是VS2015和gcc交叉着使用。

#10


一般函数模板不特化,只重载。