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++ 如何处理void decltype();_C++_Templates_C++11 - Fatal编程技术网

C++ 如何处理void decltype();

C++ 如何处理void decltype();,c++,templates,c++11,C++,Templates,C++11,我想创建一个模板,在另一个返回与成员函数相同类型的对象上调用成员函数。在成员函数上使用decltype的语法有点难看,但它似乎在除一个之外的所有情况下都能工作 这是电话: struct container: map<string, C> { template< typename MemFnPtrType, typename... _ArgTypes> auto safeOperation(string key, MemFnPtrType mfp, _Ar

我想创建一个模板,在另一个返回与成员函数相同类型的对象上调用成员函数。在成员函数上使用decltype的语法有点难看,但它似乎在除一个之外的所有情况下都能工作

这是电话:

struct container: map<string, C> 
{
    template< typename MemFnPtrType, typename... _ArgTypes>
    auto safeOperation(string key, MemFnPtrType mfp, _ArgTypes&&... args )
        -> decltype( (((C*)nullptr)->*mfp)(args...))
    {
        C* pC = NULL;
        decltype((pC->*mfp)(args...)) result;

        iterator it = find(key);
        if (it != end())
        {
            C* pC = &(it->second);
            result = (pC->*mfp)(args...);
            cout << "result:" << result << "\n";
        }
        else
        {
            cout << "key: " << key << " missing\n";
        }
        return result;
    }
};
struct容器:映射
{
模板
自动安全操作(字符串键、MemFnPtrType mfp、_ArgTypes&&…args)
->decltype(((C*)nullptr)->*mfp(args…)
{
C*pC=NULL;
decltype((pC->*mfp)(args…)结果;
迭代器it=find(键);
如果(it!=end())
{
C*pC=&(it->second);
结果=(pC->*mfp)(参数…);

cout不幸的是,我认为您在返回类型上陷入了困境。从类型特征开始(这比您的
decltype
表达式更简洁)

与:

模板
void安全操作(标准::true_type/*void*/,,
字符串键、MF mfp、Args…Args)
{ .. }
模板
Res安全操作(标准::false_类型/*非无效*/,,
字符串键、MF mfp、Args…Args)
{ .. }

这是一种极端情况。
auto
带有
decltype
的尾部返回类型不适用于
void
返回类型,因为
void
是一种不完整的类型

例如:

auto nothingMuch()
{
    return;
}

// nope
//decltype(void {}) nothingMuchEither()
//{
//  return;
//}

// nope
//auto noTrailing() -> decltype(void {})
//{
//
//}

// always works
decltype(auto) nothing()
{
    return;
}

auto main() -> decltype(int {})
{
    nothing();
    nothingMuch();
    return 0;
}

最简单的修复方法是将尾部返回类型中的
auto
decltype
替换为
decltype(auto)
作为返回类型(需要C++14).

上的标记分派是\u void
@T.C.我通常不是一个超级粉丝,但在这种情况下,它非常干净。我能够编译第一个案例,但!void case使用的语法是\u void分派似乎让我难以理解:@BitBlitz Woops!修复。完美,谢谢!为后来的人提供的工作示例:当我我想把它放在我的构建环境中GCC(4.6)太旧了,但支持丑陋的decltype()-我仍然能够用is_void标签解决void问题。虽然不漂亮,但为我节省了大量工作。再次感谢!
template <typename MF, typename... Args>
typename std::enable_if<
    std::is_same<Res<MF, Args...>, void>::value
>::type safeOperation(string key, MF mfp, Args... args)
{
     /* void case */
}

template <typename MF, typename... Args>
typename std::enable_if<
    !std::is_same<Res<MF, Args...>, void>::value,
    Res<MF, Args...>
>::type safeOperation(string key, MF mfp, Args... args)
{
     /* non-void case */
}
template <typename MF, typename... Args>
Res<MF, Args...> safeOperation(string key, MF mfp, Args... args)
{
    return safeOperation(std::is_void<Res<MF, Args...>>{},
                         key, mfp, args...);
}
template <typename MF, typename... Args>
void safeOperation(std::true_type /* void */, 
                   string key, MF mfp, Args... args) 
{ .. }

template <typename MF, typename... Args>
Res<MF, Args...> safeOperation(std::false_type /* non-void */, 
                               string key, MF mfp, Args... args) 
{ .. }
auto nothingMuch()
{
    return;
}

// nope
//decltype(void {}) nothingMuchEither()
//{
//  return;
//}

// nope
//auto noTrailing() -> decltype(void {})
//{
//
//}

// always works
decltype(auto) nothing()
{
    return;
}

auto main() -> decltype(int {})
{
    nothing();
    nothingMuch();
    return 0;
}