4

这是一个棘手的情况,我想知道有什么方法可以解决它

namespace {
  template <class T> 
  struct Template { /* ... */ }; 
}

typedef Template<int> Template;

遗憾的是,Templatetypedef 干扰Template了未命名命名空间中的模板。当您尝试Template<float>在全局范围内执行操作时,编译器会在模板名称和 typedef 名称之间引发歧义错误。

您无法控制模板名称或 typedef 名称。现在我想知道是否有可能:

  • 在全局命名空间中创建一个 typedefed 类型的对象Template(即)。Template<int>
  • Template<float>在全局命名空间中创建该类型的对象。

不允许向未命名的命名空间添加任何内容一切都应该在全局命名空间中完成。

这是出于好奇,因为我想知道有什么技巧可以解决这种歧义。这不是我在日常编程中遇到的实际问题。

4

4 回答 4

1

我知道这有点破坏你的观点,但我真的认为主要的技巧是避免像瘟疫这样的事情。

于 2010-05-28T21:33:34.153 回答
1

使用 C++0x:

namespace {
  template<class T> struct Template { };
}
typedef Template<int> Template;

#include<iostream>

template<typename T> 
void PrintType() { 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
}

template<typename FullType, typename NewParameter>
class Rebind {
  template<template<class> class Template, typename OldParameter>
  static Template<NewParameter> function(Template<OldParameter>);

public:
  typedef decltype(function(FullType())) NewType;
};

int main()
{
  PrintType< ::Template>();
  PrintType<Rebind< ::Template, float>::NewType>();
  return 0;
}

使用 gcc45 产生

void PrintType() [with T = <unnamed>::Template<int>]
void PrintType() [with T = <unnamed>::Template<float>]

显然它与 Cormeau 一起编译,但我只能访问他们的在线测试,所以我只是假设它按预期运行。

我想不出任何方法可以将实际类型直接传递给结构并将其降级为模板类型,但是当编译器必须猜测函数参数时,它可以毫无问题地剥离这两者。也许这可以在 C++03 中使用boost::result_of而不是decltype,但我以前从未使用过它,所以我想我会坚持我所知道的。

注意 内的间距main。 由于是有向图而被Rebind<::Template, float>::NewType解析器吞噬。<:我认为它会变成Rebind[:Template, float>::NewType. 所以前面的空间::Template是至关重要的。

顺便说一句,我不知道嵌套模板参数不能使用 typename [template<template<typename> class T>而不是template<template<typename> typename T>]。我想我每次尝试记住构造的语法时都会重新学习。

于 2010-05-29T10:26:48.783 回答
0

可以通过明确命名空间来访问全局类型定义模板,即

::Template a

Template<int>来自匿名命名空间的一个。不知道能不能拿到Template<float>

令人惊讶的是, Clang的 C++ 编译器可以满足以下条件,但可能不是标准行为:

#include <iostream>
namespace {
    template <class T>
        struct Template {T value;};}
typedef Template<int> Template;

int main(){    
    ::Template a;
    Template<float> b;
    a.value = 6;
    b.value = 3.14;
    std::cout<<a.value<<" "<<b.value<<"\n";
}
于 2010-05-28T21:35:59.703 回答
-1

免责声明:我不知道您为什么要这样做,并且可能会严厉地对这样做的人说话。

namespace
{
   template <typename T> class Template { };
}

typedef Template<int> IntTemplate;
typedef Template<float> FloatTemplate;
typedef IntTemplate Template;

int main() {
    ::Template t;
    FloatTemplate ft;
}
于 2010-05-28T21:38:18.013 回答