【问题标题】:Calling friend template function with no parameter defined in class template调用类模板中未定义参数的朋友模板函数
【发布时间】:2014-11-26 22:25:16
【问题描述】:

我一直在尝试调用一个没有参数的模板化友元函数,该函数在类模板中定义。我没有找到确切的解决方案并以另一种方式解决了我的问题,但是在我的实验中,我突然发现了一些有趣的代码。它有效,但我不知道为什么。这是这个例子:

#include <iostream>

template<class T> class A
{
public:
        void test() const
        {
                std::cout << "A!" << std::endl;
        }

        template<class U> friend A fun()
        {
                return A();
        }
};

int main(int argc, char* argv[])
{
        A<double> aa; // 1
        const auto& a = fun<int>();

        a.test();

        return 0;
}

正如我所说,它适用于 GCC 4.8.1。如果我删除 (1),它会失败并显示以下内容:

main.cpp: In function 'int main(int, char**)':                                                                                                                                                                     
main.cpp:20:18: error: 'fun' was not declared in this scope                                                                                                                                                        
  const auto& a = fun<int>();                                                                                                                                                                                      
                  ^                                                                                                                                                                                                
main.cpp:20:22: error: expected primary-expression before 'int'                                                                                                                                                    
  const auto& a = fun<int>();

我怀疑这里有 UB,但如果有人能澄清一下会很有趣:

  1. 为什么它在我没有告诉 fun() 它应该使用 A 的哪个特化时仍然有效?
  2. 如果不是UB,T是什么类型?我尝试了 type_info,发现它既不是 int 也不是 double。 typeid().name() 没有帮助,因为它为我返回了“FdvE”。

【问题讨论】:

  • 使用 c++filt 或一些 demangler 来解决您最后的问题。在 GCC 上,我得到 double ()
  • @remyabel 当然T 不是函数类型;)

标签: c++ templates language-lawyer friend argument-dependent-lookup


【解决方案1】:

这似乎是一个 GCC 错误。 friend 在类中定义的函数模板只能通过 ADL 找到:GCC 显然在 ADL 期间将 aa 考虑为在 main 中的调用(无缘无故)并调用 A&lt;double&gt;fun,如通过这个静态断言确认:

void test() const
{
    static_assert( std::is_same<T, double>::value, "" );
}

Demo.
Clang 完全没有 not compile this code

【讨论】:

    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 2013-09-28
    • 2020-01-28
    • 2016-10-19
    • 2017-08-08
    相关资源
    最近更新 更多