【问题标题】:Function template with reference template parameter带有引用模板参数的函数模板
【发布时间】:2012-02-09 20:55:03
【问题描述】:

有这个代码:

#include <iostream>

template<const double& f>
void fun5(){
    std::cout << f << std::endl;
} 

int main() 
{ 
    const double dddd = 5.0;
    fun5<dddd>();
    return 0;
} 

编译时出现编译器错误:

$ g++ klasa.cpp -o klasa
klasa.cpp: In function ‘int main()’:
klasa.cpp:11:10: error: ‘dddd’ cannot appear in a constant-expression
klasa.cpp:11:16: error: no matching function for call to ‘fun5()’
klasa.cpp:11:16: note: candidate is:
klasa.cpp:4:6: note: template<const double& f> void fun5()

为什么将 'dddd' 作为模板参数不起作用,应该怎样做才能使它起作用?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    模板参数的引用和指针必须具有外部链接(或内部链接,对于 C++11,但需要静态存储持续时间)。所以如果你必须使用dddd作为模板参数,你需要将它移动到全局范围并使其成为extern

    extern const double dddd = 5.0;
    int main()
    {
        fun5<dddd>();
        return 0;
    }
    

    【讨论】:

    • 你不需要做extern;正如你所说,它可以有内部联系。
    • @MikeSeymour:理论上是的,但是如果extern 被省略,gcc 和 clang 都拒绝 :(.
    • g++ 6.1 接受'extern const double dddd = 5.0;'或者只是'double dddd = 5.0;',但是'const double dddd = 5.0;'不被接受(它们都在函数 main 的全局区域中定义)
    • 添加到上面:可能是因为 const double dddd = 5.0 可以内联,以便编译器将值 5.0 放置在 dddd 变量发生的地方,并且它并没有真正表示在内存中,我不知道,只是在想
    • 从C++17开始,取消了联动限制,仍然需要静态存储时长。
    【解决方案2】:

    您可能误解了模板的用途。模板参数(尖括号之间的东西)应该是类型或整数(尽管某些实现允许浮点类型)。

    在您的情况下,最好将fun5 声明为void fun5(double&amp; f),并将其称为fun5(dddd)

    【讨论】:

    • 这不是实际情况,我只是想看看函数模板如何使用引用作为模板参数。
    猜你喜欢
    • 2012-04-10
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 2016-04-16
    • 1970-01-01
    • 2016-04-27
    相关资源
    最近更新 更多