11

这里的“不依赖”是指“不依赖于该特定函数模板的任何其他模板参数”。

在回答这个问题时,我以为我找到了答案,但根据@Johannes(在我的答案的评论中),我在这里误解了标准。举个简单的例子:

#include <type_traits>

template<class T>
struct X{
  template<class U = typename T::type>
  static void foo(int){}
  static void foo(...){}
};

int main(){
  X<std::enable_if<false>>::foo(0);
}

现场版。

是否可以保证上述编译?GCC 和 Clang 在这里不同意,正如在它们之间切换时可以在实时版本中看到的那样。有趣的是,GCC 接受了以下内容:

#include <type_traits>

template<class T>
struct X{
  template<bool = T::f()>
  static void foo(int){}
  static void foo(...){}
};

struct Y{
  static bool f(){ return true; }
};

int main(){
  X<Y>::foo(0);
}

现场版。

foo(int)第二个片段只有在T包含constexpr静态函数时才会打印f。同样,有趣的是,如果您完全删除fY或者说通过int),GCC 会抱怨缺少成员,表明它不允许 SFINAE - 这与之前的观察相矛盾。Clang 接受所有变体并应用 SFINAE,我想知道这是否是标准所保证的。

(FWIW,带有 Nov CTP 的 MSVC 通常同意 Clang,但如果该功能存在,则在第二个片段上崩溃,可能是因为他们没有。我在这里constexpr提交了错误报告。)

4

1 回答 1

3

我认为有问题的代码是不正确的,因为当类模板被实例化时,所有成员声明都被实例化,除了成员函数和成员函数模板的定义部分和默认参数。该标准还定义了函数默认参数何时被精确实例化。

因此默认模板参数会立即实例化。在我看来,此时默认参数可能旨在包含默认模板参数的可能性非常小,因为没有描述稍后何时实例化此类参数。

这符合“不应在出现在成员类之外的类模板成员的定义的模板参数列表中指定默认模板参数”的要求。,因为在实例化周围的类模板时,不可能立即实例化这样的模板参数。

于 2013-03-06T22:44:17.793 回答