【问题标题】:Decltype with template parameter带模板参数的 decltype
【发布时间】:2016-01-12 09:48:51
【问题描述】:

test1.cpp 下编译,但 test2.cpp 不编译。两者之间的唯一区别是我在 test1.cpp 的类声明中定义了Handle::add_it,但在 test2.cpp 的外部定义。

test1.cppg++ test1.cpp -o test1 -std=c++11

#include <iostream>

template<typename B>
class Handle
{
public:
        decltype(B.operator(int)) add_it(int x)
        {
                return b(x);
        }

        B b;
};

struct Add1
{
        int operator()(int x)
        {
                return x + 1;
        }
};

int main()
{
        Handle<Add1> h;
        std::cout << h.add_it(5) << std::endl;
}

test2.cppg++ test2.cpp -o test2 -std=c++11

#include <iostream>

template<typename B>
class Handle
{
public:
        decltype(B.operator(int)) add_it(int x);

        B b;
};

template<typename B>
decltype(B.operator(int)) Handle<B>::add_it(int x)
{
        return b(x);
}

struct Add1
{
        int operator()(int x)
        {
                return x + 1;
        }
};

int main()
{
        Handle<Add1> h;
        std::cout << h.add_it(5) << std::endl;
}

错误

test2.cpp:13:11: error: expected primary-expression before ‘.’ token
 decltype(B.operator(int))
           ^
test2.cpp:13:20: error: expected type-specifier before ‘(’ token
 decltype(B.operator(int))
                    ^
test2.cpp:13:21: error: expected primary-expression before ‘int’
 decltype(B.operator(int))

【问题讨论】:

  • B.operator(int) 应该是什么? #1 被 clang 拒绝,我看不出它是如何有效的语法或为什么 g++ 接受它
  • 在这种情况下,它应该是int,但在我的实际应用中,我希望它是通用的(Boperator() 的参数和返回值)。不知道为什么g++会接受,好奇自己。

标签: c++ templates c++11 decltype


【解决方案1】:

您可以使用std::declval 修改此内容:

template<typename B>
class Handle
{
public:
  decltype(std::declval<B>()(int())) add_it(int x) {
    return b(x);
  }

  B b;
};

Live Demo

或者在类的定义之外:

template<typename B>
class Handle {
public:
  decltype(std::declval<B>()(int())) add_it(int x);
  B b;
};

template<typename B>
decltype(std::declval<B>()(int())) Handle<B>::add_it(int x) {
  return b(x);
}

Live Demo

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 2017-04-11
  • 1970-01-01
  • 2022-06-23
  • 2011-04-14
相关资源
最近更新 更多